Ejemplo n.º 1
0
bool Window::IsIncluded(double left, double right) const
{
	SpiceCell cellCopy = cell;
	SpiceBoolean isIncluded = wnincd_c(left, right, &cellCopy);

	if(failed_c())
		CSpiceUtil::SignalError("Include test failed");

	return isIncluded != SPICEFALSE;
}
Ejemplo n.º 2
0
void spice::eph_impl(double mjd2000, array3D &r, array3D &v) const{
	SpiceDouble spice_epoch = kep_toolbox::util::epoch_to_spice(mjd2000);
	spkezr_c ( m_target.c_str(), spice_epoch, m_reference_frame.c_str(), m_aberrations.c_str(), m_observer.c_str(), m_state, &m_lt );
	r[0] = m_state[0] * 1000; 	r[1] = m_state[1] * 1000; 	r[2] = m_state[2] * 1000;
	v[0] = m_state[3] * 1000; 	v[1] = m_state[4] * 1000; 	v[2] = m_state[5] * 1000;
    /// Handling errors
    if (failed_c()) {
    	std::ostringstream msg;
    	msg << "SPICE cannot compute the ephemerides, have you loaded all needed Kernel files?" << std::endl;
        reset_c();
    	throw_value_error(msg.str());
    }
}
Ejemplo n.º 3
0
bool spice_error(int error_detail) {
  SpiceInt buffer_size = 1024;
  char error_message[buffer_size];


  if (failed_c()) {
    
    switch(error_detail) {
      
      case ALL :
        //TODO: Neat way to concat all error messages.
        //reset_c();
        break;

      case SHORT :
        getmsg_c("SHORT", buffer_size, error_message);
        reset_c();
        rb_raise(rb_spice_error, "%s\n", error_message);
        break;

      case LONG :
        getmsg_c("LONG", buffer_size, error_message);
        reset_c();
        rb_raise(rb_spice_error, "%s\n", error_message);
        break;

      case EXPLAIN :
        getmsg_c("EXPLAIN", buffer_size, error_message);
        reset_c();
        rb_raise(rb_spice_error, "%s\n", error_message);
        break;

      default :
        reset_c();
        break;
    }
  }
  
  return false;
}
Ejemplo n.º 4
0
   void union_c (  SpiceCell   * a,
                   SpiceCell   * b,
                   SpiceCell   * c  ) 

/*

-Brief_I/O

   VARIABLE  I/O  DESCRIPTION 
   --------  ---  -------------------------------------------------- 
   a          I   First input set. 
   b          I   Second input set. 
   c          O   Union of a and b. 
 
-Detailed_Input
 
   a           is a CSPICE set.  a must be declared as a SpiceCell 
               of data type character, double precision, or integer.

   b           is a CSPICE set, distinct from a.  b must have the 
               same data type as a.
 
-Detailed_Output
 
   c           is a CSPICE set, distinct from sets a and b, which 
               contains the union of a and b (that is, all of 
               the elements which are in a or b or both).  c must 
               have the same data type as a and b.

               When comparing elements of character sets, this routine
               ignores trailing blanks.  Trailing blanks will be 
               trimmed from the members of the output set c.

-Parameters
 
   None. 
 
-Exceptions

   1) If the input set arguments don't have identical data types,
      the error SPICE(TYPEMISMATCH) is signaled.

   2) If the union of the two sets contains more elements than can be
      contained in the output set, the error SPICE(SETEXCESS) is signaled. 

   3) If the set arguments have character type and the length of the 
      elements of the output set is less than the maximum of the 
      lengths of the elements of the input sets, the error 
      SPICE(ELEMENTSTOOSHORT) is signaled. 

   4) If either of the input arguments may be unordered or contain 
      duplicates, the error SPICE(NOTASET) is signaled.
 
-Files
 
   None. 

-Particulars

   This is a generic CSPICE set routine; it operates on sets of any
   supported data type.
 
   The union of two sets contains every element which is 
   in the first set, or in the second set, or in both sets. 

      {a,b}      union  {c,d}     =  {a,b,c,d} 
      {a,b,c}           {b,c,d}      {a,b,c,d} 
      {a,b,c,d}         {}           {a,b,c,d} 
      {}                {a,b,c,d}    {a,b,c,d} 
      {}                {}           {} 
 
-Examples
 
   1) The following code fragment places the union of the character sets
      planets and asteroids into the character set result.


         #include "SpiceUsr.h"
                .
                .
                .
         /.
         Declare the sets with string length NAMLEN and with maximum
         number of elements MAXSIZ.
         ./
         SPICECHAR_CELL ( planets,   MAXSIZ, NAMLEN );
         SPICECHAR_CELL ( asteroids, MAXSIZ, NAMLEN );
         SPICECHAR_CELL ( result,    MAXSIZ, NAMLEN );
                .
                .
                .
         /.
         Compute the union.
         ./
         union_c ( &planets, &asteroids, &result );


   2) Repeat example #1, this time using integer sets containing
      ID codes of the bodies of interest.


         #include "SpiceUsr.h"
                .
                .
                .
         /.
         Declare the sets with maximum number of elements MAXSIZ.
         ./
         SPICEINT_CELL ( planets,   MAXSIZ );
         SPICEINT_CELL ( asteroids, MAXSIZ );
         SPICEINT_CELL ( result,    MAXSIZ );
                .
                .
                .
         /.
         Compute the union.
         ./
         union_c ( &planets, &asteroids, &result );
 

   3) Construct a set containing the periapse and apoapse TDB epochs
      of an orbiter, given two separate sets containing the epochs of
      those events.


         #include "SpiceUsr.h"
                .
                .
                .
         /.
         Declare the sets with maximum number of elements MAXSIZ.
         ./
         SPICEDOUBLE_CELL ( periapse,   MAXSIZ );
         SPICEDOUBLE_CELL ( apoapse,    MAXSIZ );
         SPICEDOUBLE_CELL ( result,     MAXSIZ );
                .
                .
                .
         /.
         Compute the union.
         ./
         union_c ( &periapse, &apoapse, &result );


-Restrictions
 
   1) The output set must be distinct from both of the input sets. 
      For example, the following calls are invalid. 

         union_c  ( &current,  &new,      &current );
         union_c  ( &new,      &current,  &current );

      In each of the examples above, whether or not the subroutine 
      signals an error, the results will almost certainly be wrong. 
      Nearly the same effect can be achieved, however, by placing the 
      result into a temporary set, which is immediately copied back 
      into one of the input sets, as shown below. 

         union_c  ( &current,  &new,  &temp );
         copy_c   ( &temp,     &new         );

 
   2) String comparisons performed by this routine are Fortran-style:
      trailing blanks in the input sets are ignored. This gives
      consistent behavior with CSPICE code generated by the f2c
      translator, as well as with the Fortran SPICE Toolkit.

      Note that this behavior is not identical to that of the ANSI
      C library functions strcmp and strncmp.

-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman    (JPL) 
   C.A. Curzon     (JPL) 
   W.L. Taber      (JPL) 
   I.M. Underwood  (JPL) 
 
-Version
 
   -CSPICE Version 1.1.0, 15-FEB-2005 (NJB)

       Bug fix:  loop bound changed from 2 to 3 in loop used
       to free dynamically allocated arrays.

   -CSPICE Version 1.0.0, 08-AUG-2002 (NJB) (CAC) (WLT) (IMU)

-Index_Entries
 
   union of two sets 
 
-&
*/


{ /* Begin union_c */


   /*
   Local variables 
   */
   SpiceChar             * fCell[3];

   SpiceInt                fLen [3];
   SpiceInt                i;


   /*
   Standard SPICE error handling. 
   */
   if ( return_c() )
   {
      return;
   }

   chkin_c ( "union_c" );

   /*
   Make sure data types match. 
   */
   CELLMATCH3 ( CHK_STANDARD, "union_c", a, b, c );

   /*
   Make sure the input cells are sets.
   */
   CELLISSETCHK2 ( CHK_STANDARD, "union_c", a, b );

   /*
   Initialize the cells if necessary. 
   */
   CELLINIT3 ( a, b, c );

   /*
   Call the union routine appropriate for the data type of the cells. 
   */
   if ( a->dtype == SPICE_CHR )
   {

      /*
      Construct Fortran-style sets suitable for passing to unionc_. 
      */
      C2F_MAP_CELL3 (  "", 
                       a, fCell,   fLen,
                       b, fCell+1, fLen+1,   
                       c, fCell+2, fLen+2  );


      if ( failed_c() )
      {
         chkout_c ( "union_c" );
         return;
      }


      unionc_ ( (char    * )  fCell[0],
                (char    * )  fCell[1],
                (char    * )  fCell[2],
                (ftnlen    )  fLen[0],
                (ftnlen    )  fLen[1],
                (ftnlen    )  fLen[2]  );

      /*
      Map the union back to a C style cell. 
      */
      F2C_MAP_CELL ( fCell[2], fLen[2], c );


      /*
      We're done with the dynamically allocated Fortran-style arrays. 
      */
      for ( i = 0;  i < 3;  i++ )
      {
         free ( fCell[i] );
      }

   }

   else if ( a->dtype == SPICE_DP )
   {
      uniond_ ( (doublereal * )  (a->base),
                (doublereal * )  (b->base),
                (doublereal * )  (c->base)  );
      /*
      Sync the output cell. 
      */
      if ( !failed_c() )
      {
         zzsynccl_c ( F2C, c );
      }

   }

   else if ( a->dtype == SPICE_INT )
   {
      unioni_ ( (integer * )  (a->base),
                (integer * )  (b->base),
                (integer * )  (c->base)  );      

      /*
      Sync the output cell. 
      */
      if ( !failed_c() )
      {
         zzsynccl_c ( F2C, c );
      }
   }

   else
   {
     setmsg_c ( "Cell a contains unrecognized data type code #." );
     errint_c ( "#",  (SpiceInt) (a->dtype)                      );
     sigerr_c ( "SPICE(NOTSUPPORTED)"                            );
     chkout_c ( "union_c"                                        );
     return;
   }


   /*
   Indicate the result is a set. 
   */
   c->isSet = SPICETRUE;


   chkout_c ( "union_c" );   

} /* End union_c */
Ejemplo n.º 5
0
void gfrr_c ( ConstSpiceChar     * target,
              ConstSpiceChar     * abcorr,
              ConstSpiceChar     * obsrvr,
              ConstSpiceChar     * relate,
              SpiceDouble          refval,
              SpiceDouble          adjust,
              SpiceDouble          step,
              SpiceInt             nintvls,
              SpiceCell          * cnfine,
              SpiceCell          * result  )

/*

-Brief_I/O

   Variable  I/O  Description
   --------  ---  --------------------------------------------------
   SPICE_GF_CNVTOL   P   Convergence tolerance
   target            I   Name of the target body.
   abcorr            I   Aberration correction flag.
   obsrvr            I   Name of the observing body.
   relate            I   Relational operator.
   refval            I   Reference value.
   adjust            I   Adjustment value for absolute extrema searches.
   step              I   Step size used for locating extrema and roots.
   nintvls           I   Workspace window interval count.
   cnfine           I-O  SPICE window to which the search is confined.
   result            O   SPICE window containing results.

-Detailed_Input

   target      is the name of a target body. The target body is
               an ephemeris object; its trajectory is given by
               SPK data.

               The string `target' is case-insensitive, and leading
               and trailing blanks in `target' are not significant.
               Optionally, you may supply a string containing the
               integer ID code for the object. For example both
               "MOON" and "301" are legitimate strings that indicate
               the Moon is the target body.

               The target and observer define a position vector which
               points from the observer to the target; the time derivative
               length of this vector is the "range rate" that serves as
               the subject of the search performed by this routine.


   abcorr      indicates the aberration corrections to be applied to
               the observer-target state vector to account for
               one-way light time and stellar aberration.

               Any aberration correction accepted by the SPICE
               routine spkezr_c is accepted here. See the header
               of spkezr_c for a detailed description of the
               aberration correction options. For convenience,
               the options are listed below:

                  "NONE"     Apply no correction.

                  "LT"       "Reception" case:  correct for
                             one-way light time using a Newtonian
                             formulation.

                  "LT+S"     "Reception" case:  correct for
                             one-way light time and stellar
                             aberration using a Newtonian
                             formulation.

                  "CN"       "Reception" case:  converged
                             Newtonian light time correction.

                  "CN+S"     "Reception" case:  converged
                             Newtonian light time and stellar
                             aberration corrections.

                  "XLT"      "Transmission" case:  correct for
                             one-way light time using a Newtonian
                             formulation.

                  "XLT+S"    "Transmission" case:  correct for
                             one-way light time and stellar
                             aberration using a Newtonian
                             formulation.

                  "XCN"      "Transmission" case:  converged
                             Newtonian light time correction.

                  "XCN+S"    "Transmission" case:  converged
                             Newtonian light time and stellar
                             aberration corrections.

               Case and blanks are not significant in the string
               `abcorr'.

   obsrvr      is the name of the observing body. The observing body is
               an ephemeris object; its trajectory is given by SPK
               data. `obsrvr' is case-insensitive, and leading and
               trailing blanks in `obsrvr' are not significant.
               Optionally, you may supply a string containing the
               integer ID code for the object. For example both "MOON"
               and "301" are legitimate strings that indicate the Moon
               is the observer.

   relate      is a relational operator used to define a constraint
               on observer-target range rate. The result window found
               by this routine indicates the time intervals where
               the constraint is satisfied. Supported values of
               `relate' and corresponding meanings are shown below:

                  ">"      Distance is greater than the reference
                           value `refval'.

                  "="      Distance is equal to the reference
                           value `refval'.

                  "<"      Distance is less than the reference
                           value `refval'.


                 "ABSMAX"  Distance is at an absolute maximum.

                 "ABSMIN"  Distance is at an absolute  minimum.

                 "LOCMAX"  Distance is at a local maximum.

                 "LOCMIN"  Distance is at a local minimum.

              The caller may indicate that the region of interest
              is the set of time intervals where the quantity is
              within a specified distance of an absolute extremum.
              The argument `adjust' (described below) is used to
              specify this distance.

              Local extrema are considered to exist only in the
              interiors of the intervals comprising the confinement
              window:  a local extremum cannot exist at a boundary
              point of the confinement window.

              Case is not significant in the string `relate'.

    refval    is the reference value used together with the argument
              `relate' to define an equality or inequality to be
              satisfied by the range rate between the specified target
              and observer. See the discussion of `relate' above for
              further information.

              The units of `refval' are km/sec.

   adjust     is a parameter used to modify searches for absolute
              extrema: when `relate' is set to "ABSMAX" or "ABSMIN" and
              `adjust' is set to a positive value, gfdist_c will find
              times when the observer-target range rate is within
              `adjust' km/sec of the specified extreme value.

              If `adjust' is non-zero and a search for an absolute
              minimum `min' is performed, the result window contains
              time intervals when the observer-target range rate has
              values between `min' and min+adjust.

              If the search is for an absolute maximum `max', the
              corresponding range is from max-adjust to `max'.

              `adjust' is not used for searches for local extrema,
              equality or inequality conditions.

   step       is the step size to be used in the search. `step' must
              be short enough for a search using this step size
              to locate the time intervals where the specified
              range rate function is monotone increasing or
              decreasing. However, `step' must not be *too* short, or
              the search will take an unreasonable amount of time.

              The choice of `step' affects the completeness but not
              the precision of solutions found by this routine; the
              precision is controlled by the convergence tolerance.
              See the discussion of the parameter SPICE_GF_CNVTOL for
              details.

              `step' has units of TDB seconds.

   nintvls    is a parameter specifying the number of intervals that
              can be accommodated by each of the dynamically allocated
              windows used internally by this routine. `nintvls' should
              be at least as large as the number of intervals within
              the search region on which the specified range rate
              function is monotone increasing or decreasing. See
              the Examples section below for code examples illustrating
              the use of this parameter.

   cnfine     is a SPICE window that confines the time period over
              which the specified search is conducted. `cnfine' may
              consist of a single interval or a collection of
              intervals.

              In some cases the confinement window can be used to
              greatly reduce the time period that must be searched
              for the desired solution. See the Particulars section
              below for further discussion.

              See the Examples section below for a code example
              that shows how to create a confinement window.

-Detailed_Output

   cnfine     is the input confinement window, updated if necessary
              so the control area of its data array indicates the
              window's size and cardinality. The window data are
              unchanged.


   result     is the window of intervals, contained within the
              confinement window `cnfine', on which the specified
              constraint is satisfied.

              If `result' is non-empty on input, its contents will be
              discarded before 'gfrr_c' conducts its search.

              `result' must be declared with sufficient size to capture
              the full set of time intervals within the search region
              on which the specified constraint is satisfied.

              If the search is for local extrema, or for absolute
              extrema with `adjust' set to zero, then normally each
              interval of `result' will be a singleton: the left and
              right endpoints of each interval will be identical.

              If no times within the confinement window satisfy the
              constraint, `result' will be returned with a cardinality
              of zero.

-Parameters

   SPICE_GF_CNVTOL

              is the convergence tolerance used for finding endpoints
              of the intervals comprising the result window.
              SPICE_GF_CNVTOL is used to determine when binary searches
              for roots should terminate: when a root is bracketed
              within an interval of length SPICE_GF_CNVTOL, the root is
              considered to have been found.

              The accuracy, as opposed to precision, of roots found
              by this routine depends on the accuracy of the input
              data. In most cases, the accuracy of solutions will be
              inferior to their precision.

              SPICE_GF_CNVTOL is declared in the header file SpiceGF.h.

-Exceptions

   1)  In order for this routine to produce correct results,
       the step size must be appropriate for the problem at hand.
       Step sizes that are too large may cause this routine to miss
       roots; step sizes that are too small may cause this routine
       to run unacceptably slowly and in some cases, find spurious
       roots.

       This routine does not diagnose invalid step sizes, except
       that if the step size is non-positive, an error is signaled
       by a routine in the call tree of this routine.

   2)  Due to numerical errors, in particular,

          - Truncation error in time values
          - Finite tolerance value
          - Errors in computed geometric quantities

       it is *normal* for the condition of interest to not always be
       satisfied near the endpoints of the intervals comprising the
       result window.

       The result window may need to be contracted slightly by the
       caller to achieve desired results. The SPICE window routine
       wncond_c can be used to contract the result window.

   3)  If an error (typically cell overflow) occurs while performing
       window arithmetic, the error will be diagnosed by a routine
       in the call tree of this routine.

   4)  If the relational operator `relate' is not recognized, an
       error is signaled by a routine in the call tree of this
       routine.

   5)  If the aberration correction specifier contains an
       unrecognized value, an error is signaled by a routine in the
       call tree of this routine.

   6)  If 'adjust' is negative, the error SPICE(VALUEOUTOFRANGE) will
       signal from a routine in the call tree of this routine.

       A non-zero value for 'adjust' when 'relate' has any value other than
       "ABSMIN" or "ABSMAX" causes the error SPICE(INVALIDVALUE) to
       signal from a routine in the call tree of this routine.

   7)  If either of the input body names do not map to NAIF ID
       codes, an error is signaled by a routine in the call tree of
       this routine.

   8)  If required ephemerides or other kernel data are not
       available, an error is signaled by a routine in the call tree
       of this routine.

   9)  If the workspace interval count is less than 1, the error
       SPICE(VALUEOUTOFRANGE) will be signaled.

   10) If the required amount of workspace memory cannot be
       allocated, the error SPICE(MALLOCFAILURE) will be
       signaled.

   11) If any input string argument pointer is null, the error
       SPICE(NULLPOINTER) will be signaled.

   12) If any input string argument is empty, the error
       SPICE(EMPTYSTRING) will be signaled.

   13) If either input cell has type other than SpiceDouble,
       the error SPICE(TYPEMISMATCH) is signaled.

-Files

   Appropriate kernels must be loaded by the calling program before
   this routine is called.

   The following data are required:

      - SPK data: ephemeris data for target and observer for the
        time period defined by the confinement window must be
        loaded. If aberration corrections are used, the states of
        target and observer relative to the solar system barycenter
        must be calculable from the available ephemeris data.
        Typically ephemeris data are made available by loading one
        or more SPK files via furnsh_c.

   In all cases, kernel data are normally loaded once per program
   run, NOT every time this routine is called.

-Particulars

   This routine determines if the caller-specified constraint condition
   on the geometric event (range rate) is satisfied for any time intervals
   within the confinement window 'cnfine'. If one or more such time
   intervals exist, those intervals are added to the 'result' window.

   This routine provides a simpler, but less flexible interface
   than does the routine gfevnt_c for conducting the searches for
   observer-target range rate value events. Applications that require
   support for progress reporting, interrupt handling, non-default step
   or refinement functions, or non-default convergence tolerance should
   call gfevnt_c rather than this routine.

   Below we discuss in greater detail aspects of this routine's
   solution process that are relevant to correct and efficient
   use of this routine in user applications.


   The Search Process
   ==================

   Regardless of the type of constraint selected by the caller, this
   routine starts the search for solutions by determining the time
   periods, within the confinement window, over which the specified
   range rate function is monotone increasing and monotone decreasing.
   Each of these time periods is represented by a SPICE window. Having
   found these windows, all of the range rate function's local extrema
   within the confinement window are known. Absolute extrema then can
   be found very easily.

   Within any interval of these "monotone" windows, there will be at
   most one solution of any equality constraint. Since the boundary
   of the solution set for any inequality constraint is contained in
   the union of

      - the set of points where an equality constraint is met
      - the boundary points of the confinement window

   the solutions of both equality and inequality constraints can be
   found easily once the monotone windows have been found.


   Step Size
   =========

   The monotone windows (described above) are found via a two-step
   search process. Each interval of the confinement window is
   searched as follows: first, the input step size is used to
   determine the time separation at which the sign of the rate of
   change of range rate  will be sampled. Starting at
   the left endpoint of an interval, samples will be taken at each
   step. If a change of sign is found, a root has been bracketed; at
   that point, the time at which the range rate is zero can be
   found by a refinement process, for example, via binary search.

   Note that the optimal choice of step size depends on the lengths
   of the intervals over which the range rate function is monotone:
   the step size should be shorter than the shortest of these
   intervals (within the confinement window).

   The optimal step size is *not* necessarily related to the lengths
   of the intervals comprising the result window. For example, if
   the shortest monotone interval has length 10 days, and if the
   shortest result window interval has length 5 minutes, a step size
   of 9.9 days is still adequate to find all of the intervals in the
   result window. In situations like this, the technique of using
   monotone windows yields a dramatic efficiency improvement over a
   state-based search that simply tests at each step whether the
   specified constraint is satisfied. The latter type of search can
   miss solution intervals if the step size is longer than the
   shortest solution interval.

   Having some knowledge of the relative geometry of the target and
   observer can be a valuable aid in picking a reasonable step size.
   In general, the user can compensate for lack of such knowledge by
   picking a very short step size; the cost is increased computation
   time.

   Note that the step size is not related to the precision with which
   the endpoints of the intervals of the result window are computed.
   That precision level is controlled by the convergence tolerance.


   Convergence Tolerance
   =====================

   As described above, the root-finding process used by this routine
   involves first bracketing roots and then using a search process to
   locate them.  "Roots" include times when extrema are attained and
   times when the geometric quantity function is equal to a reference
   value or adjusted extremum. All endpoints of the intervals comprising
   the result window are either endpoints of intervals of the confinement
   window or roots.

   Once a root has been bracketed, a refinement process is used to
   narrow down the time interval within which the root must lie.
   This refinement process terminates when the location of the root
   has been determined to within an error margin called the
   "convergence tolerance." The convergence tolerance used by this
   routine is set via the parameter SPICE_GF_CNVTOL.

   The value of SPICE_GF_CNVTOL is set to a "tight" value so that the
   tolerance doesn't limit the accuracy of solutions found by this
   routine. In general the accuracy of input data will be the limiting
   factor.

   The user may change the convergence tolerance from the default
   SPICE_GF_CNVTOL value by calling the routine gfstol_c, e.g.

      gfstol_c( tolerance value in seconds )

   Call gfstol_c prior to calling this routine. All subsequent
   searches will use the updated tolerance value.

   Searches over time windows of long duration may require use of
   larger tolerance values than the default: the tolerance must be
   large enough so that it, when added to or subtracted from the
   confinement window's lower and upper bounds, yields distinct time
   values.

   Setting the tolerance tighter than SPICE_GF_CNVTOL is unlikely to be
   useful, since the results are unlikely to be more accurate.
   Making the tolerance looser will speed up searches somewhat,
   since a few convergence steps will be omitted. However, in most
   cases, the step size is likely to have a much greater effect
   on processing time than would the convergence tolerance.


   The Confinement Window
   ======================

   The simplest use of the confinement window is to specify a time
   interval within which a solution is sought. However, the
   confinement window can, in some cases, be used to make searches
   more efficient. Sometimes it's possible to do an efficient search
   to reduce the size of the time period over which a relatively
   slow search of interest must be performed.

   Consider the following example: suppose one wishes to find the
   times when the range rate between Io and the Earth attains a global
   minimum over some (lengthy) time interval. There is one local
   minimum every few days. The required step size for this search
   must be smaller than the shortest interval on which the range rate
   is monotone increasing or decreasing; this step size will be less
   than half the average time between local minima. However, we know
   that a global minimum can't occur when the Jupiter-Sun-Earth
   angle is greater than 90 degrees. We can use a step size of a
   half year to find the time period, within our original time
   interval, during which this angle is less than 90 degrees; this
   time period becomes the confinement window for our Earth-Io
   range rate search. This way we've used a quick (due to the large
   step size) search to cut out about half of the search period over
   which we must perform a slower search using a small step size.

-Examples

   The numerical results shown for these examples may differ across
   platforms. The results depend on the SPICE kernels used as
   input, the compiler and supporting libraries, and the machine
   specific arithmetic implementation.

      Use the meta-kernel shown below to load the required SPICE
      kernels.

         KPL/MK

         File name: standard.tm

         This meta-kernel is intended to support operation of SPICE
         example programs. The kernels shown here should not be
         assumed to contain adequate or correct versions of data
         required by SPICE-based user applications.

         In order for an application to use this meta-kernel, the
         kernels referenced here must be present in the user's
         current working directory.

         The names and contents of the kernels referenced
         by this meta-kernel are as follows:

            File name                     Contents
            ---------                     --------
            de421.bsp                     Planetary ephemeris
            pck00009.tpc                  Planet orientation and
                                          radii
            naif0009.tls                  Leapseconds

         \begindata

            KERNELS_TO_LOAD = ( 'de421.bsp',
                                'pck00009.tpc',
                                'naif0009.tls'  )

         \begintext

   Example:

      Determine the time windows from January 1, 2007 UTC to
      April 1, 2007 UTC for which the sun-moon range rate satisfies the
      relation conditions with respect to a reference value of
      0.3365 km/s radians (this range rate known to occur within the
      search interval). Also determine the time windows corresponding
      to the local maximum and minimum range rate, and the absolute
      maximum and minimum range rate during the search interval.

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>

      #include "SpiceUsr.h"

      #define       MAXWIN    20000
      #define       TIMFMT    "YYYY-MON-DD HR:MN:SC.###"
      #define       TIMLEN    41
      #define       NLOOPS    7

      int main( int argc, char **argv )
         {

         /.
         Create the needed windows. Note, one window
         consists of two values, so the total number
         of cell values to allocate is twice
         the number of intervals.
         ./
         SPICEDOUBLE_CELL ( result, 2*MAXWIN );
         SPICEDOUBLE_CELL ( cnfine, 2        );

         SpiceDouble       begtim;
         SpiceDouble       endtim;
         SpiceDouble       step;
         SpiceDouble       adjust;
         SpiceDouble       refval;
         SpiceDouble       beg;
         SpiceDouble       end;

         SpiceChar         begstr [ TIMLEN ];
         SpiceChar         endstr [ TIMLEN ];

         SpiceChar       * target = "MOON";
         SpiceChar       * abcorr = "NONE";
         SpiceChar       * obsrvr = "SUN";

         SpiceInt          count;
         SpiceInt          i;
         SpiceInt          j;

         ConstSpiceChar * relate [NLOOPS] = { "=",
                                              "<",
                                              ">",
                                              "LOCMIN",
                                              "ABSMIN",
                                              "LOCMAX",
                                              "ABSMAX",
                                            };

         /.
         Load kernels.
         ./
         furnsh_c( "standard.tm" );

         /.
         Store the time bounds of our search interval in
         the cnfine confinement window.
         ./
         str2et_c( "2007 JAN 01", &begtim );
         str2et_c( "2007 APR 01", &endtim );

         wninsd_c ( begtim, endtim, &cnfine );

         /.
         Search using a step size of 1 day (in units of seconds).
         The reference value is .3365 km/s. We're not using the
         adjustment feature, so we set 'adjust' to zero.
         ./
         step   = spd_c();
         adjust = 0.;
         refval = .3365;

         for ( j = 0;  j < NLOOPS;  j++ )
            {

            printf ( "Relation condition: %s \n",  relate[j] );

            /.
            Perform the search. The SPICE window 'result' contains
            the set of times when the condition is met.
            ./
            gfrr_c ( target,
                     abcorr,
                     obsrvr,
                     relate[j],
                     refval,
                     adjust,
                     step,
                     MAXWIN,
                     &cnfine,
                     &result );

            count = wncard_c( &result );

            /.
            Display the results.
            ./
            if (count == 0 )
               {
               printf ( "Result window is empty.\n\n" );
               }
            else
               {
               for ( i = 0;  i < count;  i++ )
                  {

                  /.
                  Fetch the endpoints of the Ith interval
                  of the result window.
                  ./
                  wnfetd_c ( &result, i, &beg, &end );

                  timout_c ( beg, TIMFMT, TIMLEN, begstr );
                  timout_c ( end, TIMFMT, TIMLEN, endstr );

                  printf ( "Start time, drdt = %s \n", begstr );
                  printf ( "Stop time,  drdt = %s \n", endstr );

                  }

               }

            printf("\n");

            }

         return( 0 );
         }


   The program outputs:

      Relation condition: =
      Start time, drdt = 2007-JAN-02 00:35:19.574
      Stop time,  drdt = 2007-JAN-02 00:35:19.574
      Start time, drdt = 2007-JAN-19 22:04:54.899
      Stop time,  drdt = 2007-JAN-19 22:04:54.899
      Start time, drdt = 2007-FEB-01 23:30:13.428
      Stop time,  drdt = 2007-FEB-01 23:30:13.428
      Start time, drdt = 2007-FEB-17 11:10:46.540
      Stop time,  drdt = 2007-FEB-17 11:10:46.540
      Start time, drdt = 2007-MAR-04 15:50:19.929
      Stop time,  drdt = 2007-MAR-04 15:50:19.929
      Start time, drdt = 2007-MAR-18 09:59:05.959
      Stop time,  drdt = 2007-MAR-18 09:59:05.959

      Relation condition: <
      Start time, drdt = 2007-JAN-02 00:35:19.574
      Stop time,  drdt = 2007-JAN-19 22:04:54.899
      Start time, drdt = 2007-FEB-01 23:30:13.428
      Stop time,  drdt = 2007-FEB-17 11:10:46.540
      Start time, drdt = 2007-MAR-04 15:50:19.929
      Stop time,  drdt = 2007-MAR-18 09:59:05.959

      Relation condition: >
      Start time, drdt = 2007-JAN-01 00:00:00.000
      Stop time,  drdt = 2007-JAN-02 00:35:19.574
      Start time, drdt = 2007-JAN-19 22:04:54.899
      Stop time,  drdt = 2007-FEB-01 23:30:13.428
      Start time, drdt = 2007-FEB-17 11:10:46.540
      Stop time,  drdt = 2007-MAR-04 15:50:19.929
      Start time, drdt = 2007-MAR-18 09:59:05.959
      Stop time,  drdt = 2007-APR-01 00:00:00.000

      Relation condition: LOCMIN
      Start time, drdt = 2007-JAN-11 07:03:58.988
      Stop time,  drdt = 2007-JAN-11 07:03:58.988
      Start time, drdt = 2007-FEB-10 06:26:15.439
      Stop time,  drdt = 2007-FEB-10 06:26:15.439
      Start time, drdt = 2007-MAR-12 03:28:36.404
      Stop time,  drdt = 2007-MAR-12 03:28:36.404

      Relation condition: ABSMIN
      Start time, drdt = 2007-JAN-11 07:03:58.988
      Stop time,  drdt = 2007-JAN-11 07:03:58.988

      Relation condition: LOCMAX
      Start time, drdt = 2007-JAN-26 02:27:33.766
      Stop time,  drdt = 2007-JAN-26 02:27:33.766
      Start time, drdt = 2007-FEB-24 09:35:07.816
      Stop time,  drdt = 2007-FEB-24 09:35:07.816
      Start time, drdt = 2007-MAR-25 17:26:56.150
      Stop time,  drdt = 2007-MAR-25 17:26:56.150

      Relation condition: ABSMAX
      Start time, drdt = 2007-MAR-25 17:26:56.150
      Stop time,  drdt = 2007-MAR-25 17:26:56.150

-Restrictions

   1) The kernel files to be used by this routine must be loaded
      (normally using the CSPICE routine furnsh_c) before this
      routine is called.

   2) This routine has the side effect of re-initializing the
      range rate quantity utility package. Callers may themselves
      need to re-initialize the range rate quantity utility
      package after calling this routine.

-Literature_References

   None.

-Author_and_Institution

   N.J. Bachman   (JPL)
   E.D. Wright    (JPL)

-Version

   -CSPICE Version 1.0.1, 28-FEB-2013 (NJB) (EDW)

      Header was updated to discuss use of gfstol_c.

      Edit to comments to correct search description.

      Edits to Example section, proper description of "standard.tm"
      meta kernel.

   -CSPICE Version 1.0.0, 26-AUG-2009 (EDW) (NJB)

-Index_Entries

 GF range rate search

-&
*/

{   /* Begin gfrr_c */

    /*
    Local variables
    */
    doublereal            * work;

    static SpiceInt         nw = SPICE_GF_NWRR;
    SpiceInt                nBytes;

    /*
    Participate in error tracing.
    */

    chkin_c ( "gfrr_c" );

    /*
    Make sure cell data types are d.p.
    */
    CELLTYPECHK2 ( CHK_STANDARD, "gfrr_c", SPICE_DP, cnfine, result );

    /*
    Initialize the input cells if necessary.
    */
    CELLINIT2 ( cnfine, result );

    /*
    Check the input strings to make sure each pointer is non-null
    and each string length is non-zero.
    */
    CHKFSTR ( CHK_STANDARD, "gfrr_c", target );
    CHKFSTR ( CHK_STANDARD, "gfrr_c", abcorr );
    CHKFSTR ( CHK_STANDARD, "gfrr_c", obsrvr );
    CHKFSTR ( CHK_STANDARD, "gfrr_c", relate );

    /*
    Check the workspace size; some mallocs have a violent
    dislike for negative allocation amounts. To be safe,
    rule out a count of zero intervals as well.
    */

    if ( nintvls < 1 )
    {
        setmsg_c ( "The specified workspace interval count # was "
                   "less than the minimum allowed value of one (1)." );
        errint_c ( "#",  nintvls                              );
        sigerr_c ( "SPICE(VALUEOUTOFRANGE)"                   );
        chkout_c ( "gfrr_c"                                   );
        return;
    }

    /*
    Allocate the workspace. 'nintvls' indicates the maximum number of
    intervals returned in 'result'. An interval consists of
    two values.
    */

    nintvls = 2 * nintvls;

    nBytes  = ( nintvls + SPICE_CELL_CTRLSZ ) * nw * sizeof(SpiceDouble);

    work    = (doublereal *) alloc_SpiceMemory( nBytes );

    if ( !work )
    {
        setmsg_c ( "Workspace allocation of # bytes failed due to "
                   "malloc failure"                               );
        errint_c ( "#",  nBytes                                   );
        sigerr_c ( "SPICE(MALLOCFAILED)"                          );
        chkout_c ( "gfrr_c"                                       );
        return;
    }

    /*
    Let the f2'd routine do the work.
    */

    gfrr_( ( char          * ) target,
           ( char          * ) abcorr,
           ( char          * ) obsrvr,
           ( char          * ) relate,
           ( doublereal    * ) &refval,
           ( doublereal    * ) &adjust,
           ( doublereal    * ) &step,
           ( doublereal    * ) (cnfine->base),
           ( integer       * ) &nintvls,
           ( integer       * ) &nw,
           ( doublereal    * ) work,
           ( doublereal    * ) (result->base),
           ( ftnlen          ) strlen(target),
           ( ftnlen          ) strlen(abcorr),
           ( ftnlen          ) strlen(obsrvr),
           ( ftnlen          ) strlen(relate) );

    /*
    De-allocate the workspace.
    */
    free_SpiceMemory( work );

    /*
    Sync the output cell.
    */
    if ( !failed_c() )
    {
        zzsynccl_c ( F2C, result ) ;
    }

    ALLOC_CHECK;

    chkout_c ( "gfrr_c" );

} /* End gfrr_c */
Ejemplo n.º 6
0
   int zzgfdsps_ ( integer  * nlead,
                   char     * string,
                   char     * fmt,
                   integer  * ntrail,
                   ftnlen     stringLen,
                   ftnlen     fmtLen     ) 

/*

-Brief_I/O
 
 
   VARIABLE  I/O  DESCRIPTION 
   --------  ---  -------------------------------------------------- 
   nlead      I   Number of leading blank lines to write. 
   string     I   The string to display. 
   fmt        I   Format in which the string is to be written. 
   ntrail     I   Number of trailing blank lines to write. 
   stringLen  I   Length of input argument `string'.
   fmtLen     I   Length of input argument `fmt'.
 
-Detailed_Input
 
   nlead          is the number of blank lines to write before 
                  writing the output text string. 
 
   string         is a message to be displayed on the standard 
                  output stream. This is a Fortran-style string
                  without a terminating null character.
 
   fmt            is a Fortran format specification used to write 
                  the output string. This is a Fortran-style string
                  without a terminating null character.
 
                  FMT may be left to default ("A"), or may be used 
                  to control the length of the string ("A10"). 

                  **NOTE**: this argument is provided only for
                  compatibility with the Fortran version of this
                  routine; the argument is currently ignored.
 
   ntrail         is the number of blank lines to write after 
                  writing the output text string. 

   stringLen      is the length of the input string `string'.

   fmtLen         is the length of the input string `fmt'.
 
-Detailed_Output
 
   None. This program has no output arguments but writes to the 
   standard output stream. 
 
-Parameters
 
   None. 
 
-Exceptions
 
   1) If an error occurs when this routine attempts to 
      allocate memory dynamically, the error will be
      diagnosed by routines in the call tree of this routine.
 
   2) If the either of the input arguments `nlead' or `ntrail' 
      is non-positive, then no leading or trailing blank 
      lines will be written, respectively. This case is not 
      considered an error. 
 
-Files
 
   None. 
 
-Particulars
 
   This is an overlay routine for the f2c'd routine zzgfdsps_;
   as such, this routine has an f2c-style calling sequence.

   CSPICE GF routines should call this routine rather than
   zzgfdsps_.

   Since ANSI C supports the cursor control capabilities required
   for GF progress reporting, it's not necessary to rely on ANSI
   control sequences to effect cursor control.

   This routine supports the default GF progress report display. 
   Output is written to the standard output stream; normally this 
   results in output on a terminal window. 
 
   After the output line is written, this routine moves the cursor 
   up and to the first column, so a subsequent call will overwrite 
   output from the current call. 
 
-Examples 
 
   See calls made to this routine by the entry points of 
   zzgfrpwrk. 
 
-Restrictions
 
   The input Fortran format argument is ignored.
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman     (JPL) 
 
-Version
 
   -CSPICE Version 1.0.0, 27-FEB-2009 (NJB)

-Index_Entries
 
   GF output progress report string 
 
-&
*/

{ /* Begin zzgfdsps_ */


   /*
   Local variables
   */      
   SpiceChar             * CFmtPtr;
   SpiceChar             * CStringPtr;

   SpiceInt                i;
   SpiceInt                nl;
   SpiceInt                nt;
   SpiceInt                outlen;
 

   /*
   Participate in error tracing.
   */
   chkin_c ( "zzgfdsps_" );

   /*
   The input strings are Fortran-style; they're not 
   null-terminated. Convert these to C-style strings
   so we can work with them. We'll need to use dynamic
   memory to hold the C-style strings. 
   */
   F2C_CreateStr_Sig ( stringLen, string, &CStringPtr );
   
   if ( failed_c() ) 
   {
      /*
      The CSPICE string utilities do their own clean-up of
      allocated memory, so we won't attempt to free the
      C string. 
      */
      chkout_c ( "zzgfdsps_" );

      return (-1);
   }

   F2C_CreateStr_Sig ( fmtLen, fmt, &CFmtPtr );

   if ( failed_c() ) 
   {
      /*
      Failure at this point requires that we free the previous,
      successfully allocated string. 
      */
      free ( CStringPtr );

      chkout_c ( "zzgfdsps_" );

      return(-1);
   }

   /*
   Display any blank lines indicated by `nlead'. 
   */

   nl = *nlead;
   nt = *ntrail;

 
   for ( i = 0;  i < nl; i++ )
   {
      putc ( '\n', stdout );
   }

   /*
   Save the length of the output string. 
   */
   outlen = strlen( CStringPtr );

   /*
   Write the string to standard output without a trailing newline
   character. 
   */   
   printf ( "%s", CStringPtr );  


   /*
   Force a write of any buffered, unwritten output data. 

   Without this call, progress report updates may not be displayed in a
   timely fashion. There can be a long pause, followed by an
   announcement that the task is 100% done. This behavior rather
   defeats the purpose of the report.
   */
   fflush ( stdout );

   /*
   Back up the cursor to the start of the line. 
   */
   for ( i = 0; i < outlen; i++ )
   {
      putc ( '\b', stdout );
   }

   /*
   Display any blank lines indicated by `ntrail'. 
   */
   for ( i = 0;  i < nt; i++ )
   {
      putc ( '\n', stdout );
   }

   /*
   Free the dynamically allocated strings. 
   */
   free ( CStringPtr );
   free ( CFmtPtr    );
   
   chkout_c ( "zzgfdsps_" );

   return ( 0 );


} /* End zzgfdsps_ */
Ejemplo n.º 7
0
   void wninsd_c ( SpiceDouble     left,
                   SpiceDouble     right,
                   SpiceCell     * window ) 

/*

-Brief_I/O
 
   VARIABLE  I/O  DESCRIPTION 
   --------  ---  -------------------------------------------------- 
   left, 
   right      I   Left, right endpoints of new interval. 
   window    I,O  Input, output window. 
 
-Detailed_Input
 
   left, 
   right       are the left and right endpoints of the interval 
               to be inserted. 

   window      on input, is a CSPICE window containing zero or more 
               intervals. 
 
               window must be declared as a double precision
               SpiceCell.

-Detailed_Output
 
   window      on output, is the original window following the 
               insertion of the interval from left to right. 
 
-Parameters
 
   None. 
 
-Exceptions
 
   1) If the input window does not have double precision type,
      the error SPICE(TYPEMISMATCH) is signaled.

   2) If left is greater than right, the error SPICE(BADENDPOINTS) is 
      signaled. 
 
   3) If the insertion of the interval causes an excess of elements, 
      the error SPICE(WINDOWEXCESS) is signaled. 
 
-Files
 
   None. 
 
-Particulars
 
   This routine inserts the interval from left to right into the 
   input window. If the new interval overlaps any of the intervals 
   in the window, the intervals are merged. Thus, the cardinality 
   of the input window can actually decrease as the result of an 
   insertion. However, because inserting an interval that is 
   disjoint from the other intervals in the window can increase the 
   cardinality of the window, the routine signals an error. 
 
   No other CSPICE unary window routine can increase the number of
   intervals in the input window.

-Examples
 
    Let window contain the intervals 
 
       [ 1, 3 ]  [ 7, 11 ]  [ 23, 27 ] 
 
    Then the following series of calls 
 
       wninsd_c ( 5.0,  5.0, &window )                  (1) 
       wninsd_c ( 4.0,  8.0, &window )                  (2) 
       wninsd_c ( 0.0, 30.0, &window )                  (3) 
 
    produces the following series of windows 

       [ 1,  3 ]  [ 5,  5 ]  [  7, 11 ]  [ 23, 27 ]     (1) 
       [ 1,  3 ]  [ 4, 11 ]  [ 23, 27 ]                 (2) 
       [ 0, 30 ]                                        (3) 
 
-Restrictions
 
   None. 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman    (JPL) 
   K.R. Gehringer  (JPL) 
   H.A. Neilan     (JPL) 
   W.L. Taber      (JPL) 
   I.M. Underwood  (JPL) 
 
-Version
 
   -CSPICE Version 1.0.0, 29-JUL-2002 (NJB) (KRG) (HAN) (WLT) (IMU)

-Index_Entries
 
   insert an interval into a d.p. window 
 
-&
*/

{ /* Begin wninsd_c */


   /*
   Standard SPICE error handling. 
   */

   if ( return_c() )
   {
      return;
   }
   chkin_c ( "wninsd_c" );


   /*
   Make sure cell data type is d.p. 
   */
   CELLTYPECHK ( CHK_STANDARD, "wninsd_c", SPICE_DP, window );


   /*
   Initialize the cell if necessary. 
   */
   CELLINIT ( window );
   

   /*
   Let the f2c'd routine do the work. 
   */
   wninsd_ ( (doublereal * )  &left,
             (doublereal * )  &right,
             (doublereal * )  (window->base) );

   /*
   Sync the output cell. 
   */
   if ( !failed_c() )
   {
      zzsynccl_c ( F2C, window );
   }


   chkout_c ( "wninsd_c" );

} /* End wninsd_c */
Ejemplo n.º 8
0
void pcpool_c ( ConstSpiceChar  * name,
                SpiceInt          n,
                SpiceInt          lenvals,
                const void      * cvals    )
/*

-Brief_I/O

   VARIABLE  I/O  DESCRIPTION
   --------  ---  --------------------------------------------------
   name       I   The kernel pool name to associate with cvals.
   n          I   The number of values to insert.
   lenvals    I   The lengths of the strings in the array cvals.
   cvals      I   An array of strings to insert into the kernel pool.

-Detailed_Input

   name       is the name of the kernel pool variable to associate
              with the values supplied in the array cvals. 'name' is
              restricted to a length of 32 characters or less.

   n          is the number of values to insert into the kernel pool.

   lenvals    is the length of the strings in the array cvals,
              including the null terminators.

   cvals      is an array of strings to insert into the kernel
              pool.  cvals should be declared as follows:

                 char  cvals[n][lenvals];

-Detailed_Output

   None.

-Parameters

   None.

-Exceptions

   1) If name is already present in the kernel pool and there
      is sufficient room to hold all values supplied in values,
      the old values associated with name will be overwritten.

   2) If there is not sufficient room to insert a new variable
      into the kernel pool and name is not already present in
      the kernel pool, the error SPICE(KERNELPOOLFULL) is
      signaled by a routine in the call tree to this routine.

   3) If there is not sufficient room to insert the values associated
      with name, the error SPICE(NOMOREROOM) will be signaled.

   4) If either input string pointer is null, the error
      SPICE(NULLPOINTER) will be signaled.

   5) If the input string name has length zero, the error
      SPICE(EMPTYSTRING) will be signaled.

   6) If the input cvals string length is less than 2, the error
      SPICE(STRINGTOOSHORT) will be signaled.

   7) The error 'SPICE(BADVARNAME)' signals if the kernel pool
      variable name length exceeds 32.

-Files

   None.

-Particulars

   This entry point provides a programmatic interface for inserting
   character data into the SPICE kernel pool without reading an
   external file.

-Examples

   The following example program shows how a topocentric frame for a
   point on the surface of the earth may be defined at run time using
   pcpool_c, pdpool_c, and pipool_c.  In this example, the surface
   point is associated with the body code 300000.  To facilitate
   testing, the location of the surface point coincides with that of
   the DSN station DSS-12; the reference frame MYTOPO defined here
   coincides with the reference frame DSS-12_TOPO.

      #include <stdio.h>
      #include "SpiceUsr.h"

      int main()
      {
         /.
         The first angle is the negative of the longitude of the
         surface point; the second angle is the negative of the
         point's colatitude.
         ./
         SpiceDouble             angles [3]      =  { -243.1945102442646,
                                                       -54.7000629043147,
                                                       180.0              };

         SpiceDouble             et              =    0.0;
         SpiceDouble             rmat   [3][3];

         SpiceInt                axes   [3]      =  { 3, 2, 3 };
         SpiceInt                center          =    300000;
         SpiceInt                frclass         =    4;
         SpiceInt                frclsid         =    1500000;
         SpiceInt                frcode          =    1500000;

         /.
         Define the MYTOPO reference frame.

         Note that the third argument in the pcpool_c calls is
         the length of the final string argument, including the
         terminating null character.
         ./
         pipool_c ( "FRAME_MYTOPO",            1,     &frcode   );
         pcpool_c ( "FRAME_1500000_NAME",      1, 7,  "MYTOPO"  );
         pipool_c ( "FRAME_1500000_CLASS",     1,     &frclass  );
         pipool_c ( "FRAME_1500000_CLASS_ID",  1,     &frclsid  );
         pipool_c ( "FRAME_1500000_CENTER",    1,     &center   );

         pcpool_c ( "OBJECT_300000_FRAME",     1, 7,  "MYTOPO"  );

         pcpool_c ( "TKFRAME_MYTOPO_RELATIVE", 1, 7,  "ITRF93"  );
         pcpool_c ( "TKFRAME_MYTOPO_SPEC",     1, 7,  "ANGLES"  );
         pcpool_c ( "TKFRAME_MYTOPO_UNITS",    1, 8,  "DEGREES" );
         pipool_c ( "TKFRAME_MYTOPO_AXES",     3,     axes      );
         pdpool_c ( "TKFRAME_MYTOPO_ANGLES",   3,     angles    );

         /.
         Load a high precision binary earth PCK. Also load a
         topocentric frame kernel for DSN stations. The file names
         shown here are simply examples; users should replace these
         with the names of appropriate kernels.
         ./
         furnsh_c ( "earth_000101_060207_051116.bpc" );
         furnsh_c ( "earth_topo_050714.tf"           );

         /.
         Look up transformation from DSS-12_TOPO frame to MYTOPO frame.
         This transformation should differ by round-off error from
         the identity matrix.
         ./
         pxform_c ( "DSS-12_TOPO", "MYTOPO", et, rmat );

         printf   ( "\n"
                    "DSS-12_TOPO to MYTOPO transformation at "
                    "et %23.16e = \n"
                    "\n"
                    "    %25.16f  %25.16f  %25.16f\n"
                    "    %25.16f  %25.16f  %25.16f\n"
                    "    %25.16f  %25.16f  %25.16f\n",
                    et,
                    rmat[0][0],  rmat[0][1],  rmat[0][2],
                    rmat[1][0],  rmat[1][1],  rmat[1][2],
                    rmat[2][0],  rmat[2][1],  rmat[2][2]       );

         return ( 0 );
      }


-Restrictions

   None.

-Literature_References

   None.

-Author_and_Institution

   N.J. Bachman    (JPL)
   W.L. Taber      (JPL)

-Version

   -CSPICE Version 1.3.3,  17-JAN-2014 (NJB)

      Updated Index_Entries section.

   -CSPICE Version 1.3.2,  10-FEB-2010 (EDW)

      Added mention of the restriction on kernel pool variable
      names to 32 characters or less.

      Reordered header sections to conform to SPICE convention.

   -CSPICE Version 1.3.1, 17-NOV-2005 (NJB)

      Replaced code fragment in Examples section of header with
      smaller, complete program.

   -CSPICE Version 1.3.0, 12-JUL-2002 (NJB)

      Call to C2F_CreateStrArr_Sig replaced with call to C2F_MapStrArr.

   -CSPICE Version 1.2.0, 28-AUG-2001 (NJB)

      Const-qualified input array cvals.

   -CSPICE Version 1.1.0, 14-FEB-2000 (NJB)

       Calls to C2F_CreateStrArr replaced with calls to error-signaling
       version of this routine:  C2F_CreateStrArr_Sig.

   -CSPICE Version 1.0.0, 18-JUN-1999 (NJB) (WLT)

-Index_Entries

   Set the value of a character_variable in the kernel_pool

-&
*/

{   /* Begin pcpool_c */


    /*
    Local variables
    */
    SpiceChar             * fCvalsArr;

    SpiceInt                fCvalsLen;


    /*
    Participate in error tracing.
    */
    chkin_c ( "pcpool_c" );

    /*
    Check the input kernel variable name to make sure the pointer is
    non-null and the string length is non-zero.
    */
    CHKFSTR ( CHK_STANDARD, "pcpool_c", name );


    /*
    Make sure the input string pointer for the cvals array is non-null
    and that the length lenvals is sufficient.
    */
    CHKOSTR ( CHK_STANDARD, "pcpool_c", cvals, lenvals );


    /*
    Create a Fortran-style string array.
    */
    C2F_MapStrArr ( "pcpool_c",
                    n, lenvals, cvals, &fCvalsLen, &fCvalsArr );

    if ( failed_c() )
    {
        chkout_c ( "pcpool_c" );
        return;
    }


    /*
    Call the f2c'd routine.
    */
    pcpool_ (  ( char       * ) name,
               ( integer    * ) &n,
               ( char       * ) fCvalsArr,
               ( ftnlen       ) strlen(name),
               ( ftnlen       ) fCvalsLen     );


    /*
    Free the dynamically allocated array.
    */
    free ( fCvalsArr );


    chkout_c ( "pcpool_c" );

} /* End pcpool_c */
Ejemplo n.º 9
0
  /** 
   * This method looks for any naif errors that might have occurred. It 
   * then compares the error to a list of known naif errors and converts
   * the error into an iException.
   * 
   * @param resetNaif True if the NAIF error status should be reset (naif calls valid)
   */
  void NaifStatus::CheckErrors(bool resetNaif) {
    if(!initialized) {
      SpiceChar returnAct[32] = "RETURN";
      SpiceChar printAct[32] = "NONE";
      erract_c ( "SET", sizeof(returnAct), returnAct); // Reset action to return
      errprt_c ( "SET", sizeof(printAct), printAct);   // ... and print nothing
      initialized = true;
    }

    // Do nothing if NAIF didn't fail
    //getmsg_c("", 0, NULL);
    if(!failed_c()) return;

    // This method has been documented with the information provided
    //   from the NAIF documentation at:
    //    naif/cspice61/packages/cspice/doc/html/req/error.html


    // This message is a character string containing a very terse, usually 
    // abbreviated, description of the problem. The message is a character 
    // string of length not more than 25 characters. It always has the form:
    // SPICE(...)
    // Short error messages used in CSPICE are CONSTANT, since they are 
    // intended to be used in code. That is, they don't contain any data which 
    // varies with the specific instance of the error they indicate.
    // Because of the brief format of the short error messages, it is practical 
    // to use them in a test to determine which type of error has occurred. 
    const int SHORT_DESC_LEN = 26;
    SpiceChar naifShort[SHORT_DESC_LEN];
    getmsg_c("SHORT", SHORT_DESC_LEN, naifShort);

    // This message may be up to 1840 characters long. The CSPICE error handling 
    // mechanism makes no use of its contents. Its purpose is to provide human-readable 
    // information about errors. Long error messages generated by CSPICE routines often 
    // contain data relevant to the specific error they describe.
    const int LONG_DESC_LEN = 1841;
    SpiceChar naifLong[LONG_DESC_LEN];
    getmsg_c("LONG", LONG_DESC_LEN, naifLong);

    // Search for known naif errors...
    iString errMsg;

    Pvl error;
    PvlGroup errorDescription("ErrorDescription");
    errorDescription.AddKeyword(PvlKeyword("ShortMessage", naifShort));
    errorDescription.AddKeyword(PvlKeyword("LongMessage", naifLong));
    error.AddGroup(errorDescription);

    PvlTranslationManager trans(error, "$base/translations/NaifErrors.trn");

    try {
      errMsg = trans.Translate("ShortMessage");
    }
    catch(iException &e) {
      e.Clear();
      errMsg = "An unknown NAIF error has been encountered.";
    }

    try {
      errMsg += " " + trans.Translate("LongMessage");
    }
    catch(iException &e) {
      e.Clear();
    }

    // Now process the error
    if(resetNaif) {
      reset_c();
    }

    errMsg += " The short explanation ";
    errMsg += "provided by NAIF is [" + iString(naifShort) + "]. "; 
    errMsg += "The Naif error is [" + iString(naifLong) + "]";

    throw iException::Message(iException::Spice, errMsg, _FILEINFO_);
  }
Ejemplo n.º 10
0
   void wnintd_c ( SpiceCell  * a,
                   SpiceCell  * b,
                   SpiceCell  * c ) 

/*

-Brief_I/O
 
   VARIABLE  I/O  DESCRIPTION 
   --------  ---  -------------------------------------------------- 
   a, 
   b          I   Input windows. 
   c          O   Intersection of a and b. 
 
-Detailed_Input
 
   a, 
   b           are CSPICE windows, each of which contains zero or more 
               intervals. 
 
               a and b must be declared as double precision 
               SpiceCells.

-Detailed_Output
 
   c           is the output CSPICE window, containing the intersection 
               of a and b---every point contained in both a and b. 
 
               c must be declared as a double precision SpiceCell.

               c must be distinct from both a and b. 
 
-Parameters
 
   None. 
 
-Exceptions
 
   1) If any of the function arguments are SpiceCells of type
      other than double precision, the error SPICE(TYPEMISMATCH)
      is signaled.

   2) If the intersection of the two windows results in an excess of 
      elements, the error SPICE(WINDOWEXCESS) is signaled. 
 
-Files
 
   None. 

-Particulars
 
   The intersection of two windows contains every point contained 
   both in the first window and in the second window. 
 
-Examples
 
   Let a contain the intervals 
 
      [ 1, 3 ]  [ 7, 11 ]  [ 23, 27 ] 
 
   and b contain the intervals 
 
      [ 2, 4 ]  [ 8, 10 ]  [ 16, 18 ] 
 
   Then the intersection of a and b contains the intervals 
 
      [ 2, 3 ]  [ 8, 10 ] 
  
-Restrictions
 
   None. 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman    (JPL)
   H.A. Neilan     (JPL) 
   B.V. Semenov    (JPL) 
   W.L. Taber      (JPL) 
   I.M. Underwood  (JPL) 
 
-Version
 
   -CSPICE Version 1.0.1, 11-FEB-2013 (BVS)

       Corrected typo in Brief I/O section.

   -CSPICE Version 1.0.0, 29-JUL-2002 (NJB) (HAN) (WLT) (IMU)

-Index_Entries
 
   intersect two d.p. windows 
 
-&
*/

{ /* Begin wnintd_c */

 
   /*
   Participate in error tracing.
   */
   if ( return_c() )
   {
      return;
   }
   chkin_c ( "wnintd_c" );

   /*
   Make sure cell data types are d.p. 
   */
   CELLTYPECHK3 ( CHK_STANDARD, "wnintd_c", SPICE_DP, a, b, c );


   /*
   Initialize the cells if necessary. 
   */
   CELLINIT3 ( a, b, c );
   

   /*
   Let the f2c'd routine do the work. 
   */
   wnintd_ ( (doublereal * ) (a->base),
             (doublereal * ) (b->base), 
             (doublereal * ) (c->base)  );

   /*
   Sync the output cell. 
   */
   if ( !failed_c() )
   {
      zzsynccl_c ( F2C, c );
   }


   chkout_c ( "wnintd_c" );

} /* End wnintd_c */
Ejemplo n.º 11
0
   void uddc_c ( void            ( * udfunc ) ( SpiceDouble    x,
                                                SpiceDouble  * value ),
                 SpiceDouble         x,
                 SpiceDouble         dx,
                 SpiceBoolean      * isdecr )
                     
/*
-Brief_I/O

   VARIABLE  I/O  DESCRIPTION
   --------  ---  --------------------------------------------------

   udfunc     I   The routine that computes the scalar value
                  of interest.
   x          I   Independent variable of 'udfunc'.
   dx         I   Interval from 'x' for derivative calculation.
   isdecr     O   Boolean indicating if the derivative is negative.

-Detailed_Input

   udfunc     the routine that returns the value of the scalar quantity  
              function of interest at X. The calling sequence for UDFUNC is: 
 
                 udfunc ( x, &value ); 
 
              where: 
 
                 x       the double precision value of the  
                         independent variable of the function 
                         at which to determine the scalar value. 
 
                 value   the double precision value returned by  
                         'udfunc' at 'x'. 
 
              Functionally: 
 
                 value = udfunc ( x ) 
 
   x          a scalar double precision value at which to determine 
              the derivative of 'udfunc'. 
 
              For many SPICE uses, 'x' will represent ephemeris time,  
              expressed as seconds past J2000 TDB. 
 
  dx         a scalar double precision value representing half the  
              interval in units of 'x' separating the evaluation 
              values of 'udfunc'; the evaluations occur at (x + dx)  
              and (x - dx). 
 
              'dx' may be negative but must be non-zero. 

-Detailed_Output

   isdecr   a scalar boolean indicating if the first derivative
            of 'udfunc' with respect to time at 'et' is less than 
            zero.

            Functionally:

              d udfunc(x) |
              --          |  <  0
              dx          |
                           x

-Parameters

   None.

-Exceptions
 
   1) A routine in the call tree of this routine signals 
      SPICE(DIVIDEBYZERO) if DX has a value of zero. 
 
-Files
 
   If the evaluation of 'udfunc' requires SPICE kernel data, the 
   appropriate kernels must be loaded before calling this routine. 
 
      - SPK data: the calling application must load ephemeris data 
        for the targets, observer, and any intermediate objects in  
        a chain connecting the targets and observer for the time 
        used in the evaluation. If aberration corrections are used,  
        the states of target and observer relative to the solar system  
        barycenter must be calculable from the available ephemeris  
        data. 
 
      - If non-inertial reference frames are used, then PCK 
        files, frame kernels, C-kernels, and SCLK kernels may be 
        needed. 
 
   Such kernel data are normally loaded once per program run, NOT  
   every time this routine is called.  
   
-Particulars

   None.

-Examples

   See gfuds_c.

-Restrictions

   None.

-Literature_References

   None.

-Author_and_Institution

   N.J. Bachman   (JPL)
   E.D. Wright    (JPL)
 
-Version

   -CSPICE Version 1.0.0, 31-MAR-2010 (EDW) 

-Index_Entries

   first derivative less-than zero

-&
*/

   {

   SpiceDouble               deriv;

   /*
   Participate in error tracing.
   */
   if ( return_c() )
     {
      return;
      }
   chkin_c ( "uddc_c" );

   *isdecr = SPICEFALSE;

   uddf_c ( udfunc, x, dx, &deriv );

   if ( failed_c() )
     {
     chkout_c ( "uddc_c" );
     return;
     }

   *isdecr = deriv <  0.;

   chkout_c ( "uddc_c" );
   return;
   }
Ejemplo n.º 12
0
   void gfpa_c ( ConstSpiceChar     * target,
                 ConstSpiceChar     * illmn,
                 ConstSpiceChar     * abcorr,
                 ConstSpiceChar     * obsrvr,
                 ConstSpiceChar     * relate,
                 SpiceDouble          refval,
                 SpiceDouble          adjust,
                 SpiceDouble          step,
                 SpiceInt             nintvls,
                 SpiceCell          * cnfine,
                 SpiceCell          * result     )

/*

-Brief_I/O

   Variable         I/O  Description
   ---------------  ---  ------------------------------------------------
   SPICE_GF_CNVTOL   P   Convergence tolerance
   target            I   Name of the target body.
   illmn             I   Name of the illuminating body.
   abcorr            I   Aberration correction flag.
   obsrvr            I   Name of the observing body.
   relate            I   Relational operator.
   refval            I   Reference value.
   adjust            I   Adjustment value for absolute extrema searches.
   step              I   Step size used for locating extrema and roots.
   nintvls           I   Workspace window interval count.
   cnfine           I-O  SPICE window to which the search is confined.
   result            O   SPICE window containing results.

-Detailed_Input

   target      is the name of a target body. Optionally, you may supply
               a string containing the integer ID code for the object.
               For example both "MOON" and "301" are legitimate strings
               that indicate the Moon is the target body.

               Case and leading or trailing blanks are not significant
               in the string `target'.

   illmn       the string name of the illuminating body. This will
               normally be "SUN" but the algorithm can use any
               ephemeris object

               Case and leading or trailing blanks are not significant
               in the string `illmn'.

   abcorr      indicates the aberration corrections to be applied to
               the observer-target position vector to account for
               one-way light time and stellar aberration.

               Any aberration correction accepted by the SPICE
               routine spkezr_c is accepted here. See the header
               of spkezr_c for a detailed description of the
               aberration correction options. For convenience,
               the allowed aberation options are listed below:

                  "NONE"     Apply no correction.

                  "LT"       "Reception" case:  correct for
                             one-way light time using a Newtonian
                             formulation.

                  "LT+S"     "Reception" case:  correct for
                             one-way light time and stellar
                             aberration using a Newtonian
                             formulation.

                  "CN"       "Reception" case:  converged
                             Newtonian light time correction.

                  "CN+S"     "Reception" case:  converged
                             Newtonian light time and stellar
                             aberration corrections.

               Note that this routine accepts only reception mode
               aberration corrections.

               Case and leading or trailing blanks are not significant
               in the string `abcorr'.

   obsrvr      is the name of the observing body. Optionally, you may
               supply a string containing the integer ID code for the
               object. For example both "MOON" and "301" are legitimate
               strings that indicate the Moon is the observer.

               Case and leading or trailing blanks are not significant
               in the string `obsrvr'.

   relate      is a relational operator used to define a constraint on
               the phase angle. The result window found by
               this routine indicates the time intervals where the
               constraint is satisfied. Supported values of `relate'
               and corresponding meanings are shown below:

                  ">"       The phase angle value is greater than the
                            reference value REFVAL.

                  "="       The phase angle value is equal to the
                            reference value REFVAL.

                  "<"       The phase angle value is less than the
                            reference value REFVAL.

                  "ABSMAX"  The phase angle value is at an absolute
                            maximum.

                  "ABSMIN"  The phase angle value is at an absolute
                            minimum.

                  "LOCMAX"  The phase angle value is at a local
                            maximum.

                  "LOCMIN"  The phase angle value is at a local
                            minimum.

               `relate' may be used to specify an "adjusted" absolute
               extremum constraint: this requires the phase angle
               to be within a specified offset relative to an
               absolute extremum. The argument `adjust' (described
               below) is used to specify this offset.

               Local extrema are considered to exist only in the
               interiors of the intervals comprising the confinement
               window:  a local extremum cannot exist at a boundary
               point of the confinement window.

               Case and leading or trailing blanks are not significant
               in the string `relate'.

   `refval'    is the reference value used together with the argument
               `relate' to define an equality or inequality to be
               satisfied by the phase angle. See the discussion of
               `relate' above for further information.

               The units of `refval' are radians.

   adjust      is a parameter used to modify searches for absolute
               extrema: when `relate' is set to "ABSMAX" or "ABSMIN"
               and `adjust' is set to a positive value, gfpa_c will
               find times when the phase angle is within
               `adjust' radians of the specified extreme value.

               If `adjust' is non-zero and a search for an absolute
               minimum `min' is performed, the result window contains
               time intervals when the phase angle has values between
                `min' and min+adjust.

               If the search is for an absolute maximum `max', the
               corresponding range is from max-adjust to `max'.

               `adjust' is not used for searches for local extrema,
               equality or inequality conditions.

   step        is the step size to be used in the search. `step' must
               be shorter than any maximal time interval on which the
               specified phase angle function is monotone increasing or
               decreasing. That is, if the confinement window is
               partitioned into alternating intervals on which the
               phase angle function is either monotone increasing or
               decreasing, `step' must be shorter than any of these
               intervals.

               However, `step' must not be *too* short, or the search
               will take an unreasonable amount of time.

               The choice of `step' affects the completeness but not
               the precision of solutions found by this routine; the
               precision is controlled by the convergence tolerance.
               See the discussion of the parameter SPICE_GF_CNVTOL for
               details.

               STEP has units of TDB seconds.

   nintvls     is a parameter specifying the number of intervals that
               can be accommodated by each of the dynamically allocated
               workspace windows used internally by this routine.

               In many cases, it's not necessary to compute an accurate
               estimate of how many intervals are needed; rather, the
               user can pick a size considerably larger than what's
               really required.

               However, since excessively large arrays can prevent
               applications from compiling, linking, or running
               properly, sometimes `nintvls' must be set according to
               the actual workspace requirement. A rule of thumb for
               the number of intervals needed is

                  nintvls  =  2*n  +  ( m / step )

               where

                  n     is the number of intervals in the confinement
                        window

                  m     is the measure of the confinement window, in
                        units of seconds

                  `step'  is the search step size in seconds

   cnfine      is a SPICE window that confines the time period over
               which the specified search is conducted. `cnfine' may
               consist of a single interval or a collection of
               intervals.

               The endpoints of the time intervals comprising `cnfine'
               are interpreted as seconds past J2000 TDB.

               See the Examples section below for a code example that
               shows how to create a confinement window.

-Detailed_Output

   cnfine      is the input confinement window, updated if necessary so
               the control area of its data array indicates the
               window's size and cardinality. The window data are
               unchanged.

   result      is the window of intervals, contained within the
               confinement window `cnfine', on which the specified
               phase angle constraint is satisfied.

               The endpoints of the time intervals comprising `result'
               are interpreted as seconds past J2000 TDB.

               If `result' is non-empty on input, its contents will be
               discarded before gfpa_c conducts its search.

-Parameters

   SPICE_GF_CNVTOL

               is the convergence tolerance used for finding endpoints
               of the intervals comprising the result window.
               SPICE_GF_CNVTOL is used to determine when binary
               searches for roots should terminate: when a root is
               bracketed within an interval of length SPICE_GF_CNVTOL,
               the root is considered to have been found.

               The accuracy, as opposed to precision, of roots found by
               this routine depends on the accuracy of the input data.
               In most cases, the accuracy of solutions will be
               inferior to their precision.

               SPICE_GF_CNVTOL is declared in the header file
               SpiceGF.h.

-Exceptions

   1)  In order for this routine to produce correct results,
       the step size must be appropriate for the problem at hand.
       Step sizes that are too large may cause this routine to miss
       roots; step sizes that are too small may cause this routine
       to run unacceptably slowly and in some cases, find spurious
       roots.

       This routine does not diagnose invalid step sizes, except
       that if the step size is non-positive, an error is signaled
       by a routine in the call tree of this routine.

   2)  Due to numerical errors, in particular,

          - Truncation error in time values
          - Finite tolerance value
          - Errors in computed geometric quantities

       it is *normal* for the condition of interest to not always be
       satisfied near the endpoints of the intervals comprising the
       result window.

       The result window may need to be contracted slightly by the
       caller to achieve desired results. The SPICE window routine
       wncond_c can be used to contract the result window.

   3)  If an error (typically cell overflow) occurs while performing
       window arithmetic, the error will be diagnosed by a routine
       in the call tree of this routine.

   4)  If the relational operator `relate' is not recognized, an
       error is signaled by a routine in the call tree of this
       routine.

   5)  If the aberration correction specifier contains an
       unrecognized value, an error is signaled by a routine in the
       call tree of this routine.

   6)  If `adjust' is negative, an error is signaled by a routine in
       the call tree of this routine.

   7)  If either of the input body names do not map to NAIF ID
       codes, an error is signaled by a routine in the call tree of
       this routine.

   8)  If required ephemerides or other kernel data are not
       available, an error is signaled by a routine in the call tree
       of this routine.

   9)  If the workspace interval count is less than 1, the error
       SPICE(VALUEOUTOFRANGE) will be signaled.

   10) If the required amount of workspace memory cannot be
       allocated, the error SPICE(MALLOCFAILURE) will be
       signaled.

   11) If the output SPICE window `result' has insufficient capacity to
       contain the number of intervals on which the specified geometric
       condition is met, the error will be diagnosed by a routine in
       the call tree of this routine. If the result window has size
       less than 2, the error SPICE(INVALIDDIMENSION) will be signaled
       by this routine.

   12) If any input string argument pointer is null, the error
       SPICE(NULLPOINTER) will be signaled.

   13) If any input string argument is empty, the error
       SPICE(EMPTYSTRING) will be signaled.

   14) If either input cell has type other than SpiceDouble,
       the error SPICE(TYPEMISMATCH) is signaled.

   15) An error signals from a routine in the call tree of
       this routine for any transmit mode aberration correction.

-Files

   Appropriate SPK and PCK kernels must be loaded by the calling
   program before this routine is called.

   The following data are required:

      - SPK data: the calling application must load ephemeris data
        for the targets, observer, and any intermediate objects in
        a chain connecting the targets and observer that cover the
        time period specified by the window CNFINE. If aberration
        corrections are used, the states of target and observer
        relative to the solar system barycenter must be calculable
        from the available ephemeris data. Typically ephemeris data
        are made available by loading one or more SPK files using
        furnsh_c.

   Kernel data are normally loaded once per program run, NOT every
   time this routine is called.

-Particulars

                     ILLMN      OBS
     ILLMN as seen      *       /
     from TARG at       |      /
     ET - LT.           |     /
                       >|..../< phase angle
                        |   /
                      . |  /
                    .   | /
                   .     *     TARG as seen from OBS
             SEP   .   TARG    at ET
                    .  /
                      /
                     *

   This routine determines if the caller-specified constraint
   condition on the geometric event (phase angle) is satisfied for
   any time intervals within the confinement window `cnfine'. If one
   or more such time intervals exist, those intervals are added
   to the `result' window.

   This routine provides a simpler, but less flexible interface
   than does the routine gfevnt_c for conducting searches for
   illuminator-target-observer phase angle value events.
   Applications that require support for progress reporting,
   interrupt handling, non-default step or refinement functions
   should call gfevnt_c rather than this routine.

   Below we discuss in greater detail aspects of this routine's
   solution process that are relevant to correct and efficient
   use of this routine in user applications.


   The Search Process
   ==================

   Regardless of the type of constraint selected by the caller, this
   routine starts the search for solutions by determining the time
   periods, within the confinement window, over which the
   phase angle function is monotone increasing and monotone
   decreasing. Each of these time periods is represented by a SPICE
   window. Having found these windows, all of the phase angle
   function's local extrema within the confinement window are known.
   Absolute extrema then can be found very easily.

   Within any interval of these "monotone" windows, there will be at
   most one solution of any equality constraint. Since the boundary
   of the solution set for any inequality constraint is contained in
   the union of

      - the set of points where an equality constraint is met
      - the boundary points of the confinement window

   the solutions of both equality and inequality constraints can be
   found easily once the monotone windows have been found.


   Step Size
   =========

   The monotone windows (described above) are found using a two-step
   search process. Each interval of the confinement window is
   searched as follows: first, the input step size is used to
   determine the time separation at which the sign of the rate of
   change of phase angle will be sampled. Starting at
   the left endpoint of an interval, samples will be taken at each
   step. If a change of sign is found, a root has been bracketed; at
   that point, the time at which the time derivative of the
   phase angle is zero can be found by a refinement process, for
   example, using a binary search.

   Note that the optimal choice of step size depends on the lengths
   of the intervals over which the phase angle function is monotone:
   the step size should be shorter than the shortest of these
   intervals (within the confinement window).

   The optimal step size is *not* necessarily related to the lengths
   of the intervals comprising the result window. For example, if
   the shortest monotone interval has length 10 days, and if the
   shortest result window interval has length 5 minutes, a step size
   of 9.9 days is still adequate to find all of the intervals in the
   result window. In situations like this, the technique of using
   monotone windows yields a dramatic efficiency improvement over a
   state-based search that simply tests at each step whether the
   specified constraint is satisfied. The latter type of search can
   miss solution intervals if the step size is longer than the
   shortest solution interval.

   Having some knowledge of the relative geometry of the target,
   illumination source, and observer can be a valuable aid in
   picking a reasonable step size. In general, the user can
   compensate for lack of such knowledge by picking a very short
   step size; the cost is increased computation time.

   Note that the step size is not related to the precision with which
   the endpoints of the intervals of the result window are computed.
   That precision level is controlled by the convergence tolerance.


   Convergence Tolerance
   =====================

   As described above, the root-finding process used by this routine
   involves first bracketing roots and then using a search process to
   locate them.  "Roots" include times when extrema are attained and
   times when the geometric quantity function is equal to a reference
   value or adjusted extremum. All endpoints of the intervals comprising
   the result window are either endpoints of intervals of the confinement
   window or roots.

   Once a root has been bracketed, a refinement process is used to
   narrow down the time interval within which the root must lie.
   This refinement process terminates when the location of the root
   has been determined to within an error margin called the
   "convergence tolerance." The convergence tolerance used by this
   routine is set via the parameter SPICE_GF_CNVTOL.

   The value of SPICE_GF_CNVTOL is set to a "tight" value so that the
   tolerance doesn't limit the accuracy of solutions found by this
   routine. In general the accuracy of input data will be the limiting
   factor.

   The user may change the convergence tolerance from the default
   SPICE_GF_CNVTOL value by calling the routine gfstol_c, e.g.

      gfstol_c( tolerance value in seconds )

   Call gfstol_c prior to calling this routine. All subsequent
   searches will use the updated tolerance value.

   Searches over time windows of long duration may require use of
   larger tolerance values than the default: the tolerance must be
   large enough so that it, when added to or subtracted from the
   confinement window's lower and upper bounds, yields distinct time
   values.

   Setting the tolerance tighter than SPICE_GF_CNVTOL is unlikely to be
   useful, since the results are unlikely to be more accurate.
   Making the tolerance looser will speed up searches somewhat,
   since a few convergence steps will be omitted. However, in most
   cases, the step size is likely to have a much greater effect
   on processing time than would the convergence tolerance.


   The Confinement Window
   ======================

   The simplest use of the confinement window is to specify a time
   interval within which a solution is sought. However, the
   confinement window can, in some cases, be used to make searches
   more efficient. Sometimes it's possible to do an efficient search
   to reduce the size of the time period over which a relatively
   slow search of interest must be performed. See the "CASCADE"
   example program in gf.req for a demonstration.

-Examples

   The numerical results shown for these examples may differ across
   platforms. The results depend on the SPICE kernels used as
   input, the compiler and supporting libraries, and the machine
   specific arithmetic implementation.

      Use the meta-kernel shown below to load the required SPICE
      kernels.

         KPL/MK

         File name: standard.tm

         This meta-kernel is intended to support operation of SPICE
         example programs. The kernels shown here should not be
         assumed to contain adequate or correct versions of data
         required by SPICE-based user applications.

         In order for an application to use this meta-kernel, the
         kernels referenced here must be present in the user's
         current working directory.

         The names and contents of the kernels referenced
         by this meta-kernel are as follows:

            File name                     Contents
            ---------                     --------
            de421.bsp                     Planetary ephemeris
            pck00009.tpc                  Planet orientation and
                                          radii
            naif0009.tls                  Leapseconds

         \begindata

            KERNELS_TO_LOAD = ( 'de421.bsp',
                                'pck00009.tpc',
                                'naif0009.tls'  )

         \begintext

   Example:

      Determine the time windows from December 1, 2006 UTC to
      January 31, 2007 UTC for which the sun-moon-earth configuration
      phase angle satisfies the relation conditions with respect to a
      reference value of .57598845 radians (the phase angle at
      January 1, 2007 00:00:00.000 UTC, 33.001707 degrees). Also
      determine the time windows corresponding to the local maximum and
      minimum phase angles, and the absolute maximum and minimum phase
      angles during the search interval. The configuration defines the
      sun as the illuminator, the moon as the target, and the earth as
      the observer.

      #include <stdio.h>
      #include "SpiceUsr.h"

      #define  TIMFMT  "YYYY MON DD HR:MN:SC.###"
      #define  NINTVL  5000
      #define  TIMLEN  41
      #define  NLOOPS  7

      int main()
         {

         /.
         Local variables
         ./
         SpiceChar               begstr [ TIMLEN ];
         SpiceChar               endstr [ TIMLEN ];

         SPICEDOUBLE_CELL      ( cnfine, 2 );
         SPICEDOUBLE_CELL      ( result, NINTVL*2 );

         SpiceDouble             adjust;
         SpiceDouble             et0;
         SpiceDouble             et1;
         SpiceDouble             phaseq;
         SpiceDouble             refval;
         SpiceDouble             start;
         SpiceDouble             step;
         SpiceDouble             stop;
         SpiceInt                i;
         SpiceInt                j;

         /.
         Define the values for target, observer, illuminator, and
         aberration correction.
         ./

         ConstSpiceChar * target = "moon";
         ConstSpiceChar * illmn  = "sun";
         ConstSpiceChar * abcorr = "lt+s";
         ConstSpiceChar * obsrvr = "earth";

         ConstSpiceChar * relate [NLOOPS] = { "=",
                                              "<",
                                              ">",
                                              "LOCMIN",
                                              "ABSMIN",
                                              "LOCMAX",
                                              "ABSMAX",
                                            };

         /.
         Load kernels.
         ./
         furnsh_c ( "standard.tm" );

         /.
         Store the time bounds of our search interval in
         the confinement window.
         ./
         str2et_c ( "2006 DEC 01", &et0 );
         str2et_c ( "2007 JAN 31", &et1 );

         wninsd_c ( et0, et1, &cnfine );

         /.
         Search using a step size of 1 day (in units of seconds).
         The reference value is 0.57598845 radians. We're not using the
         adjustment feature, so we set ADJUST to zero.
         ./
         step   = spd_c();
         refval = 0.57598845;
         adjust = 0.0;

         for ( j = 0;  j < NLOOPS;  j++ )
            {

            printf ( "Relation condition: %s\n",  relate[j] );

            /.
            Perform the search. The SPICE window `result' contains
            the set of times when the condition is met.
            ./
            gfpa_c ( target,    illmn,   abcorr, obsrvr,
                     relate[j], refval,  adjust, step,
                     NINTVL,    &cnfine, &result        );

            /.
            Display the results.
            ./
            if ( wncard_c(&result) == 0 )
               {
               printf ( "Result window is empty.\n\n" );
               }
            else
               {

               for ( i = 0;  i < wncard_c(&result);  i++ )
                  {

                  /.
                  Fetch the endpoints of the Ith interval
                  of the result window.
                  ./
                  wnfetd_c ( &result, i, &start, &stop );

                  phaseq = phaseq_c ( start, target, illmn, obsrvr, abcorr );

                  timout_c ( start, TIMFMT, TIMLEN, begstr );
                  printf ( "Start time = %s %16.9f\n", begstr, phaseq );

                  phaseq = phaseq_c ( stop, target, illmn, obsrvr, abcorr );

                  timout_c ( stop, TIMFMT, TIMLEN, endstr );
                  printf ( "Stop time  = %s %16.9f\n", endstr, phaseq );
                  }

               printf("\n");

               }

            }

         return ( 0 );
         }

   The program outputs:

      Relation condition: =
      Start time = 2006 DEC 02 13:31:34.414      0.575988450
      Stop time  = 2006 DEC 02 13:31:34.414      0.575988450
      Start time = 2006 DEC 07 14:07:55.470      0.575988450
      Stop time  = 2006 DEC 07 14:07:55.470      0.575988450
      Start time = 2006 DEC 31 23:59:59.997      0.575988450
      Stop time  = 2006 DEC 31 23:59:59.997      0.575988450
      Start time = 2007 JAN 06 08:16:25.512      0.575988450
      Stop time  = 2007 JAN 06 08:16:25.512      0.575988450
      Start time = 2007 JAN 30 11:41:32.557      0.575988450
      Stop time  = 2007 JAN 30 11:41:32.557      0.575988450

      Relation condition: <
      Start time = 2006 DEC 02 13:31:34.414      0.575988450
      Stop time  = 2006 DEC 07 14:07:55.470      0.575988450
      Start time = 2006 DEC 31 23:59:59.997      0.575988450
      Stop time  = 2007 JAN 06 08:16:25.512      0.575988450
      Start time = 2007 JAN 30 11:41:32.557      0.575988450
      Stop time  = 2007 JAN 31 00:00:00.000      0.468279091

      Relation condition: >
      Start time = 2006 DEC 01 00:00:00.000      0.940714974
      Stop time  = 2006 DEC 02 13:31:34.414      0.575988450
      Start time = 2006 DEC 07 14:07:55.470      0.575988450
      Stop time  = 2006 DEC 31 23:59:59.997      0.575988450
      Start time = 2007 JAN 06 08:16:25.512      0.575988450
      Stop time  = 2007 JAN 30 11:41:32.557      0.575988450

      Relation condition: LOCMIN
      Start time = 2006 DEC 05 00:16:50.317      0.086121423
      Stop time  = 2006 DEC 05 00:16:50.317      0.086121423
      Start time = 2007 JAN 03 14:18:31.977      0.079899769
      Stop time  = 2007 JAN 03 14:18:31.977      0.079899769

      Relation condition: ABSMIN
      Start time = 2007 JAN 03 14:18:31.977      0.079899769
      Stop time  = 2007 JAN 03 14:18:31.977      0.079899769

      Relation condition: LOCMAX
      Start time = 2006 DEC 20 14:09:10.392      3.055062862
      Stop time  = 2006 DEC 20 14:09:10.392      3.055062862
      Start time = 2007 JAN 19 04:27:54.600      3.074603891
      Stop time  = 2007 JAN 19 04:27:54.600      3.074603891

      Relation condition: ABSMAX
      Start time = 2007 JAN 19 04:27:54.600      3.074603891
      Stop time  = 2007 JAN 19 04:27:54.600      3.074603891

-Restrictions

   1) The kernel files to be used by this routine must be loaded
      (normally using the CSPICE routine furnsh_c) before this
      routine is called.

-Literature_References

   None.

-Author_and_Institution

   N.J. Bachman   (JPL)
   E.D. Wright    (JPL)

-Version

   -CSPICE Version 1.0.0, 15-JUL-2014 (EDW) (NJB)

-Index_Entries

 GF phase angle search

-&
*/

{ /* Begin gfpa_c */

   /*
   Static local variables
   */
   static SpiceInt         nw  =  SPICE_GF_NWPA;

   /*
   Local variables
   */
   doublereal            * work;

   SpiceInt                nBytes;


   /*
   Participate in error tracing.
   */
   if ( return_c() )
      {
      return;
      }
   chkin_c ( "gfpa_c" );


   /*
   Make sure cell data types are d.p.
   */
   CELLTYPECHK2 ( CHK_STANDARD, "gfpa_c", SPICE_DP, cnfine, result );

   /*
   Initialize the input cells if necessary.
   */
   CELLINIT2 ( cnfine, result );

   /*
   Check the input strings to make sure each pointer is non-null
   and each string length is non-zero.
   */
   CHKFSTR ( CHK_STANDARD, "gfpa_c", target );
   CHKFSTR ( CHK_STANDARD, "gfpa_c", illmn  );
   CHKFSTR ( CHK_STANDARD, "gfpa_c", abcorr );
   CHKFSTR ( CHK_STANDARD, "gfpa_c", obsrvr );
   CHKFSTR ( CHK_STANDARD, "gfpa_c", relate );

   /*
   Check the workspace size; some mallocs have a violent
   dislike for negative allocation amounts. To be safe,
   rule out a count of zero intervals as well.
   */
   if ( nintvls < 1 )
      {
      setmsg_c ( "The specified workspace interval count # was "
                 "less than the minimum allowed value (1)."     );
      errint_c ( "#",  nintvls                                  );
      sigerr_c ( "SPICE(VALUEOUTOFRANGE)"                       );
      chkout_c ( "gfpa_c"                                      );
      return;
      }

   /*
   Allocate the workspace.

   We have `nw' "doublereal" cells, each having cell size 2*nintvls.
   Each cell also has a control area containing SPICE_CELL_CTRLSZ
   double precision values.
   */

   nintvls = nintvls * 2;

   nBytes  = ( nintvls + SPICE_CELL_CTRLSZ ) * nw * sizeof(SpiceDouble);

   work    = (doublereal *) alloc_SpiceMemory( nBytes );

   if ( !work )
      {
      setmsg_c ( "Workspace allocation of # bytes failed due to "
                 "malloc failure"                                 );
      errint_c ( "#",  nBytes                                     );
      sigerr_c ( "SPICE(MALLOCFAILURE)"                           );
      chkout_c ( "gfpa_c"                                         );
      return;
      }

   /*
   Let the f2'd routine do the work.
   */
   gfpa_ ( ( char          * ) target,
           ( char          * ) illmn,
           ( char          * ) abcorr,
           ( char          * ) obsrvr,
           ( char          * ) relate,
           ( doublereal    * ) &refval,
           ( doublereal    * ) &adjust,
           ( doublereal    * ) &step,
           ( doublereal    * ) (cnfine->base),
           ( integer       * ) &nintvls,
           ( integer       * ) &nw,
           ( doublereal    * ) work,
           ( doublereal    * ) (result->base),
           ( ftnlen          ) strlen(target),
           ( ftnlen          ) strlen(illmn),
           ( ftnlen          ) strlen(abcorr),
           ( ftnlen          ) strlen(obsrvr),
           ( ftnlen          ) strlen(relate) );

   /*
   De-allocate the workspace.
   */
   free_SpiceMemory( work );

   /*
   Sync the output cell.
   */
   if ( !failed_c() )
      {
      zzsynccl_c ( F2C, result ) ;
      }

   ALLOC_CHECK;

   chkout_c ( "gfpa_c" );

} /* End gfpa_c */
Ejemplo n.º 13
0
   void lmpool_c ( const void  * cvals,
                   SpiceInt      lenvals,
                   SpiceInt      n       ) 

/*

-Brief_I/O
 
   VARIABLE  I/O  DESCRIPTION 
   --------  ---  -------------------------------------------------- 
   cvals      I   An array that contains a SPICE text kernel.
   lenvals    I   Length of strings in cvals.
   n          I   The number of entries in cvals. 
 
-Detailed_Input
 
   cvals          is an array of strings that contains lines of text 
                  that could serve as a SPICE text kernel.  cvals is 
                  declared as follows:
              
                     ConstSpiceChar   cvals [n][lenvals]
              
                  Each string in cvals is null-terminated.
              
   lenvals        is the common length of the strings in cvals,
                  including the terminating nulls.
              
   n              is the number of strings in cvals. 
 
-Detailed_Output
 
   None. 
 
-Parameters
 
   None. 
 
-Exceptions
 
   1) If the input string pointer is null, the error SPICE(NULLPOINTER) 
      will be signaled.

   2) If the input string length lenvals is not at least 2, the error
      SPICE(STRINGTOOLSHORT) will be signaled.

   3) The error 'SPICE(BADVARNAME)' signals if a kernel pool
      variable name length exceeds 32.

   4) Other exceptions are diagnosed by routines in the call tree of 
      this routine.
-Files
 
   None. 
 
-Particulars
 
   This routine allows you to store a text kernel in an internal 
   array of your program and load this array into the kernel pool 
   without first storing its contents as a text kernel. 

   Kernel pool variable names are restricted to a length of 32
   characters or less.
 
-Examples
 
   Suppose that your application is not particularly sensitive 
   to the current number of leapseconds but that you would 
   still like to use a relatively recent leapseconds kernel 
   without requiring users to load a leapseconds kernel into 
   the program.  The example below shows how you might set up 
   the initialization portion of your program. 
 
      #include "SpiceUsr.h"
      
      #define LNSIZE          81
      #define NLINES          27
      
      SpiceChar               textbuf[NLINES][LNSIZE] = 
                     {
                        "DELTET/DELTA_T_A = 32.184",
                        "DELTET/K         = 1.657D-3",
                        "DELTET/EB        = 1.671D-2",
                        "DELTET/M         = ( 6.239996 1.99096871D-7 )",
                        "DELTET/DELTA_AT  = ( 10, @1972-JAN-1",
                        "                     11, @1972-JUL-1",
                        "                     12, @1973-JAN-1",
                        "                     13, @1974-JAN-1",
                        "                     14, @1975-JAN-1",
                        "                     15, @1976-JAN-1",
                        "                     16, @1977-JAN-1",
                        "                     17, @1978-JAN-1",
                        "                     18, @1979-JAN-1",
                        "                     19, @1980-JAN-1",
                        "                     20, @1981-JUL-1",
                        "                     21, @1982-JUL-1",
                        "                     22, @1983-JUL-1",
                        "                     23, @1985-JUL-1",
                        "                     24, @1988-JAN-1",
                        "                     25, @1990-JAN-1",
                        "                     26, @1991-JAN-1",
                        "                     27, @1992-JUL-1",
                        "                     28, @1993-JUL-1",
                        "                     29, @1994-JUL-1",
                        "                     30, @1996-JAN-1",
                        "                     31, @1997-JUL-1",
                        "                     32, @1999-JAN-1 )"
                     };
                      
      lmpool_c ( textbuf, LNSIZE, NLINES );
 
 
-Restrictions
 
   None. 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman    (JPL)
   W.L. Taber      (JPL) 
 
-Version

   -CSPICE Version 1.3.1,  10-FEB-2010 (EDW)

      Added mention of the restriction on kernel pool variable 
      names to 32 characters or less.

   -CSPICE Version 1.3.0, 12-JUL-2002 (NJB)

      Call to C2F_CreateStrArr_Sig replaced with call to C2F_MapStrArr.

   -CSPICE Version 1.2.0, 28-AUG-2001 (NJB)

      Const-qualified input array.

   -CSPICE Version 1.1.0, 14-FEB-2000 (NJB)

       Calls to C2F_CreateStrArr replaced with calls to error-signaling 
       version of this routine:  C2F_CreateStrArr_Sig.
      
   -CSPICE Version 1.0.0, 08-JUN-1999 (NJB) (WLT) 

-Index_Entries
 
   Load the kernel pool from an internal text buffer 
 
-&
*/

{ /* Begin lmpool_c */



   /*
   Local variables
   */

   SpiceChar             * fCvalsArr;

   SpiceInt                fCvalsLen;


   /*
   Participate in error tracing.
   */
   chkin_c ( "lmpool_c" );

   /*
   Make sure the input string pointer is non-null and that the
   length lenvals is sufficient.  
   */
   CHKOSTR ( CHK_STANDARD, "lmpool_c", cvals, lenvals );


   /*
   Create a Fortran-style string array.
   */
   C2F_MapStrArr ( "lmpool_c", n, lenvals, cvals, &fCvalsLen, &fCvalsArr );

   if ( failed_c() )
   {
      chkout_c ( "lmpool_c" );
      return;
   }


   /*
   Call the f2c'd routine.
   */
   lmpool_ (  ( char       * ) fCvalsArr,
              ( integer    * ) &n,
              ( ftnlen       ) fCvalsLen );


   /*
   Free the dynamically allocated array.
   */
   free ( fCvalsArr );
   
   chkout_c ( "lmpool_c" );

} /* End lmpool_c */
Ejemplo n.º 14
0
   SpiceBoolean wnreld_c ( SpiceCell       * a,
                           ConstSpiceChar  * op,
                           SpiceCell       * b   )

/*

-Brief_I/O
 
   VARIABLE  I/O  DESCRIPTION 
   --------  ---  -------------------------------------------------- 
   a          I   First window. 
   op         I   Comparison operator. 
   b          I   Second window. 

   The function returns the result of comparison: a (op) b. 
 
-Detailed_Input
 
   a, 
   b           are CSPICE windows, each of which contains zero or more 
               intervals. 

               a and b must be declared as double precision SpiceCells.


   op          is a comparison operator, indicating the way in 
               which the input sets are to be compared. op may 
               be any of the following: 

                  Operator             Meaning 
                  --------  ------------------------------------- 
                    "="     a = b is SPICETRUE if a and b are equal 
                            (contain the same intervals). 

                    "<>"    a <> b is SPICETRUE if a and b are not 
                            equal. 

                    "<="    a <= b is SPICETRUE if a is a subset of b. 

                    "<"     a < b is SPICETRUE is a is a proper subset 
                            of b. 

                    ">="    a >= b is SPICETRUE if b is a subset of a. 

                    ">"     a > b is SPICETRUE if b is a proper subset 
                            of a. 

-Detailed_Output
 
   The function returns the result of the comparison. 
 
-Parameters
 
   None. 
 
-Exceptions
 
   1) If any of the function arguments are SpiceCells of type
      other than double precision, the error SPICE(TYPEMISMATCH)
      is signaled.

   2) If the relational operator is not recognized, the error 
      SPICE(INVALIDOPERATION) is signaled. 
 
   3) The error SPICE(EMPTYSTRING) is signaled if the input operator
      string does not contain at least one character, since the
      input string cannot be converted to a Fortran-style string
      in this case.
      
   4) The error SPICE(NULLPOINTER) is signalled if the input operator
      string pointer is null.

-Files
 
   None. 
 
-Particulars
 
   This function returns SPICETRUE whenever the specified relationship 
   between the input windows a and b is satisfied. For example, 
   the expression 

      wnreld_c ( &needed, "<=", &avail )

   is SPICETRUE whenever the window needed is a subset of the window 
   avail. One window is a subset of another window if each of 
   the intervals in the first window is included in one of the 
   intervals in the second window. In addition, the first window 
   is a proper subset of the second if the second window contains 
   at least one point not contained in the first window. (Thus, 
   "<" implies "<=", and ">" implies ">=".) 

   The following pairs of expressions are equivalent. 

      wnreld_c ( &a, ">",  &b ); 
      wnreld_c ( &b, "<",  &a ); 

      wnreld_c ( &a, ">=", &b ); 
      wnreld_c ( &b, "<=", &a ); 

-Examples
 
   Let a contain the intervals 

      [ 1, 3 ]  [ 7, 11 ]  [ 23, 27 ] 

   Let b and c contain the intervals 

      [ 1, 2 ]  [ 9, 9 ]  [ 24, 27 ] 

   Let d contain the intervals 

      [ 5, 10 ]  [ 15, 25 ] 

   Finally, let e and f be empty windows (containing no intervals). 

   Because b and c contain the same intervals, 

      wnreld_c ( &b, "=",  &c ) 
      wnreld_c ( &b, "<=", &c ) 
      wnreld_c ( &b, ">=", &c ) 

   are all SPICETRUE, while 

      wnreld_c ( &b, "<>", &c ) 

   is SPICEFALSE. Because neither b nor c contains any points not also 
   contained by the other, neither is a proper subset of the other. 
   Thus, 

      wnreld_c ( &b, "<", &c ) 
      wnreld_c ( &b, ">", &c ) 

   are both SPICEFALSE. 

   Every point contained in b and c is also contained in a. Thus, 

      wnreld_c ( &b, "<=", &a ) 
      wnreld_c ( &a, ">=", &c ) 

   are both SPICETRUE. In addition, a contains points not contained in 
   b and c. (That is, the differences a-b and a-c are not empty.) 
   Thus, b and c are peoper subsets of a as well, and 

      wnreld_c ( &b, "<", &a ) 
      wnreld_c ( &a, ">", &b ) 

   are both SPICETRUE. 

   Although a and d have points in common, neither contains the 
   other. Thus 

      wnreld_c ( &a, "=",  &d ) 
      wnreld_c ( &a, "<=", &d ) 
      wnreld_c ( &a, ">=", &d ) 

   are all SPICEFALSE. 

   In addition, any window is equal to itself, a subset of itself, 
   and a superset of itself. Thus, 

      wnreld_c ( &a, "=",  &a ) 
      wnreld_c ( &a, "<=", &a ) 
      wnreld_c ( &a, ">=", &a ) 

   are always SPICETRUE. However, no window is a proper subset or a 
   proper superset of itself. Thus, 

      wnreld_c ( &a, "<", &a ) 
      wnreld_c ( &a, ">", &a ) 

   are always SPICEFALSE. 

   Finally, an empty window is a proper subset of any window 
   except another empty window. Thus, 

      wnreld_c ( &e, "<", &a ) 

   is SPICETRUE, but 

      wnreld_c ( &e, "<", &f ) 

   is SPICEFALSE. 


-Restrictions
 
   None. 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman    (JPL)
   H.A. Neilan     (JPL) 
   W.L. Taber      (JPL) 
   I.M. Underwood  (JPL) 
 
-Version
 
   -CSPICE Version 1.0.0, 27-JUL-2002 (NJB) (HAN) (WLT) (IMU)

-Index_Entries
 
   compare two d.p. windows 
 
-&
*/

{ /* Begin wnreld_c */

   /*
   Local variables 
   */
   SpiceBoolean            retval;



   /*
   Participate in error tracing.
   */
   if ( failed_c() )
   {
      return ( SPICEFALSE );
   }
   chkin_c ( "wnreld_c" );


   /*
   Check the input string str to make sure the pointer is non-null 
   and the string length is non-zero.
   */
   CHKFSTR_VAL ( CHK_STANDARD, "wnreld_c", op, SPICEFALSE );


   /*
   Make sure cell data types are d.p. 
   */
   CELLTYPECHK2_VAL ( CHK_STANDARD, 
                      "wnreld_c",   SPICE_DP,  a,  b,  SPICEFALSE );


   /*
   Initialize the cells if necessary. 
   */
   CELLINIT2 ( a, b );


   /*
   Let the f2c'd routine do the work. 
   */
   retval = wnreld_ ( (doublereal * ) (a->base),
                      (char       * ) op, 
                      (doublereal * ) (b->base),
                      (ftnlen       ) strlen(op)  );


   chkout_c ( "wnreld_c" );

   return ( retval );
   
} /* End wnreld_c */
Ejemplo n.º 15
0
   void ekaclc_c ( SpiceInt                handle,
                   SpiceInt                segno,
                   ConstSpiceChar        * column,
                   SpiceInt                vallen,
                   const void            * cvals,
                   ConstSpiceInt         * entszs,
                   ConstSpiceBoolean     * nlflgs,
                   ConstSpiceInt         * rcptrs,
                   SpiceInt              * wkindx  )
/*

-Brief_I/O
 
   Variable  I/O  Description 
   --------  ---  -------------------------------------------------- 
   handle     I   EK file handle. 
   segno      I   Number of segment to add column to. 
   column     I   Column name. 
   vallen     I   Length of character values.
   cvals      I   Character values to add to column. 
   entszs     I   Array of sizes of column entries. 
   nlflgs     I   Array of null flags for column entries. 
   rcptrs     I   Record pointers for segment. 
   wkindx    I-O  Work space for column index. 
 
-Detailed_Input
 
   handle         the handle of an EK file that is open for writing. 
                  A "begin segment for fast write" operation must 
                  have already been performed for the designated 
                  segment. 
 
   segno          is the number of the segment to which data is to be
                  added. Segments are numbered from 0 to nseg-1, where
                  nseg is the count of segments in the file.

   column         is the name of the column to be added.  All of 
                  the data for the named column will be added in 
                  one shot. 
 
   vallen         is the length of the strings in the cvals array.
                  The array should be declared with dimensions
                  
                     [nrows][vallen]
                     
                  where nrows is the number of rows in the column.
   
   cvals          is an array containing the entire set of column 
                  entries for the specified column.  The entries 
                  are listed in row-order:  the column entry for the 
                  first row of the segment is first, followed by the 
                  column entry for the second row, and so on.  The 
                  number of column entries must match the declared 
                  number of rows in the segment.  For columns having 
                  fixed-size entries, a null entry must be allocated 
                  the same amount of space occupied by a non-null 
                  entry in the array cvals.  For columns having 
                  variable-size entries, null entries do not require 
                  any space in the cvals* array, but in any case must 
                  have their allocated space described correctly by 
                  the corresponding element of the entszs array 
                  (described below). 
 
   entszs         is an array containing sizes of column entries. 
                  The Ith element of entszs gives the size of the 
                  Ith column entry.  entszs is used only for columns 
                  having variable-size entries.  For such columns, 
                  the dimension of entszs must be at least nrows. 
                  The size of null entries should be set to zero. 
 
                  For columns having fixed-size entries, the 
                  dimension of this array may be any positive value. 
 
   nlflgs         is an array of logical flags indicating whether 
                  the corresponding entries are null.  If the Ith 
                  element of nlflgs is SPICEFALSE, the Ith column entry 
                  defined by cvals and entszs is added to the 
                  current segment in the specified kernel file. 
 
                  If the Ith element of nlfgls is SPICETRUE, the 
                  contents of the Ith column entry are undefined. 
 
                  nlflgs is used only for columns that allow null 
                  values; it's ignored for other columns. 
 
   rcptrs         is an array of record pointers for the input 
                  segment.  This array is obtained as an output 
                  from ekifld_c, the routine called to initiate a 
                  fast write. 
 
   wkindx         is a work space array used for building a column 
                  index.  If the column is indexed, the dimension of 
                  wkindx_c must be at nrows, where nrows is the number 
                  of rows in the column.  If the column is not 
                  indexed, this work space is not used, so the 
                  dimension may be any positive value. 
 
-Detailed_Output
 
   None.  See $Particulars for a description of the effect of this 
   routine. 
 
-Parameters
 
   None. 
 
-Exceptions
 
   1)  If handle is invalid, the error will be diagnosed by routines 
       called by this routine. 
 
   2)  If column is not the name of a declared column, the error
       SPICE(NOCOLUMN) will be signaled.
        
   3)  If column specifies a column of whose data type is not 
       character, the error SPICE(WRONGDATATYPE) will be 
       signalled. 
 
   4)  If the specified column already contains ANY entries, the 
       error will be diagnosed by routines called by this routine. 
 
   5)  If an I/O error occurs while reading or writing the indicated 
       file, the error will be diagnosed by routines called by this 
       routine. 
 
   6) If the string pointer for column is null, the error 
      SPICE(NULLPOINTER) will be signaled.
      
   7) If the input string column has length zero, the error 
      SPICE(EMPTYSTRING) will be signaled.
 
   8) If the string pointer for cvals is null, the error
      SPICE(NULLPOINTER) will be signaled.
     
   9) If the string length vallen is less than 2, the error 
      SPICE(STRINGTOOSHORT) will be signaled.
    
-Files
 
   See the EK Required Reading for a discussion of the EK file 
   format. 
 
-Particulars
 
   This routine operates by side effects:  it modifies the named 
   EK file by adding data to the specified column.  This routine 
   writes the entire contents of the specified column in one shot. 
   This routine creates columns much more efficiently than can be 
   done by sequential calls to ekacec_c, but has the drawback that 
   the caller must use more memory for the routine's inputs.  This 
   routine cannot be used to add data to a partially completed 
   column. 
 
-Examples
 
   1)  Suppose we have an E-kernel named order_db.ek which contains 
       records of orders for data products.  The E-kernel has a 
       table called DATAORDERS that consists of the set of columns 
       listed below: 
 
          DATAORDERS 
 
             Column Name     Data Type 
             -----------     --------- 
             ORDER_ID        INTEGER 
             CUSTOMER_ID     INTEGER 
             LAST_NAME       CHARACTER*(*) 
             FIRST_NAME      CHARACTER*(*) 
             ORDER_DATE      TIME 
             COST            DOUBLE PRECISION 
 
       The order database also has a table of items that have been 
       ordered.  The columns of this table are shown below: 
 
          DATAITEMS 
 
             Column Name     Data Type 
             -----------     --------- 
             ITEM_ID         INTEGER 
             ORDER_ID        INTEGER 
             ITEM_NAME       CHARACTER*(*) 
             DESCRIPTION     CHARACTER*(*) 
             PRICE           DOUBLE PRECISION 
 
 
       We'll suppose that the file ORDER_DB.EK contains two segments, 
       the first containing the DATAORDERS table and the second 
       containing the DATAITEMS table. 
 
       Below, we show how we'd open a new EK file and create the 
       first of the segments described above. 
 
       #include "SpiceUsr.h"
       #include <stdio.h>
       
       
       void main()
       {
          /.
          Constants
          ./
          #define  CNMLEN      ( CSPICE_EK_COL_NAM_LEN + 1 )
          #define  DECLEN        201
          #define  EKNAME        "order_db.ek"
          #define  FNMLEN        50
          #define  IFNAME        "Test EK/Created 20-SEP-1995"
          #define  LNMLEN        50
          #define  LSK           "leapseconds.ker"
          #define  NCOLS         6
          #define  NRESVC        0
          #define  NROWS         9
          #define  TABLE         "DATAORDERS"
          #define  TNMLEN        CSPICE_EK_TAB_NAM_LEN
          #define  UTCLEN        30
          
          
          /.
          Local variables
          ./
          SpiceBoolean            nlflgs [ NROWS  ];
       
          SpiceChar               cdecls  [ NCOLS ] [ DECLEN ];
          SpiceChar               cnames  [ NCOLS ] [ CNMLEN ];
          SpiceChar               fnames  [ NROWS ] [ FNMLEN ];
          SpiceChar               lnames  [ NROWS ] [ LNMLEN ];
          SpiceChar               dateStr [ UTCLEN ];
        
          SpiceDouble             costs  [ NROWS ];
          SpiceDouble             ets    [ NROWS ];
       
          SpiceInt                cstids [ NROWS ];
          SpiceInt                ordids [ NROWS ];
          SpiceInt                handle;
          SpiceInt                i;
          SpiceInt                rcptrs [ NROWS ];
          SpiceInt                segno;
          SpiceInt                sizes  [ NROWS ];
          SpiceInt                wkindx [ NROWS ];
          
          
          /.
          Load a leapseconds kernel for UTC/ET conversion.
          ./
          furnsh_c ( LSK );
          
          /.
          Open a new EK file.  For simplicity, we will not 
          reserve any space for the comment area, so the 
          number of reserved comment characters is zero. 
          The constant IFNAME is the internal file name. 
          ./
          ekopn_c ( EKNAME, IFNAME, NRESVC, &handle );
       
          /.
          Set up the table and column names and declarations 
          for the DATAORDERS segment.  We'll index all of 
          the columns.  All columns are scalar, so we omit 
          the size declaration.  Only the COST column may take 
          null values. 
          ./
          strcpy ( cnames[0], "ORDER_ID"                           );
          strcpy ( cdecls[0], "DATATYPE = INTEGER, INDEXED = TRUE" );
       
          strcpy ( cnames[1], "CUSTOMER_ID"                        );
          strcpy ( cdecls[1], "DATATYPE = INTEGER, INDEXED = TRUE" );
       
          strcpy ( cnames[2], "LAST_NAME"                          ); 
          strcpy ( cdecls[2], "DATATYPE = CHARACTER*(*),"
                              "INDEXED  = TRUE"                    );
       
          strcpy ( cnames[3], "FIRST_NAME"                         );
          strcpy ( cdecls[3], "DATATYPE = CHARACTER*(*),"   
                              "INDEXED  = TRUE"                    );
       
          strcpy ( cnames[4], "ORDER_DATE"                         );
          strcpy ( cdecls[4], "DATATYPE = TIME, INDEXED  = TRUE"   );
       
          strcpy ( cnames[5], "COST"                               );
          strcpy ( cdecls[5], "DATATYPE = DOUBLE PRECISION,"   
                              "INDEXED  = TRUE,"             
                              "NULLS_OK = TRUE"                    );
       
          /.
          Start the segment.  We presume the number of  rows 
          of data is known in advance. 
          ./
          ekifld_c ( handle,  TABLE,   NCOLS,  NROWS,   CNMLEN,  
                     cnames,  DECLEN,  cdecls, &segno,  rcptrs );
       
          /.
          At this point, arrays containing data for the 
          segment's columns may be filled in.  The names 
          of the data arrays are shown below. 
       
             Column           Data array 
       
             "ORDER_ID"       ordids 
             "CUSTOMER_ID"    cstids 
             "LAST_NAME"      lnames 
             "FIRST_NAME"     fnames 
             "ORDER_DATE"     odates 
             "COST"           costs 
       
       
          The null flags array indicates which entries are null. 
          It is ignored for columns that don't allow null 
          values.  In this case, only the COST column allows 
          nulls. 
          
          Fill in data arrays and null flag arrays here.  This code
          section would normally be replaced by calls to user functions
          returning column values.
          ./
          
          for ( i = 0;  i < NROWS;  i++ )
          {
             ordids[i]  =  i;
             cstids[i]  =  i*100;
             costs [i]  =  (SpiceDouble) 100*i;
       
             sprintf  ( fnames[i], "Order %d Customer first name", i );
             sprintf  ( lnames[i], "Order %d Customer last name",  i );
             sprintf  ( dateStr,   "1998 Mar %d",                  i );
             
             utc2et_c ( dateStr, ets+i );
       
             nlflgs[i]  =  SPICEFALSE;
          }
       
          nlflgs[1] = SPICETRUE;
          
          
          /.
          The sizes array shown below is ignored for scalar 
          and fixed-size array columns, so we need not 
          initialize it.  For variable-size arrays, the 
          Ith element of the sizes array must contain the size 
          of the Ith column entry in the column being written. 
          Normally, the sizes array would be reset for each 
          variable-size column. 
       
          Add the columns of data to the segment.  All of the 
          data for each column is written in one shot. 
          ./
          ekacli_c ( handle,  segno,   "order_id",    ordids, 
                     sizes,   nlflgs,  rcptrs,        wkindx ); 
       
          ekacli_c ( handle,  segno,   "customer_id", cstids,  
                     sizes,   nlflgs,  rcptrs,        wkindx ); 
       
          ekaclc_c ( handle,  segno,   "last_name",   LNMLEN,
                     lnames,  sizes,   nlflgs,        rcptrs,  wkindx ); 
       
          ekaclc_c ( handle,  segno,   "first_name",  FNMLEN,
                     fnames,  sizes,   nlflgs,        rcptrs,  wkindx ); 
       
          ekacld_c ( handle,  segno,   "order_date",  ets,  
                     sizes,   nlflgs,  rcptrs,        wkindx );
          
          ekacld_c ( handle,  segno,   "cost",        costs,  
                     sizes,   nlflgs,  rcptrs,        wkindx ); 
       
          /.
          Complete the segment.  The rcptrs array is that 
          returned by ekifld_c. 
          ./
          ekffld_c ( handle, segno, rcptrs ); 
       
          /.
          At this point, the second segment could be 
          created by an analogous process.  In fact, the 
          second segment could be created at any time; it is 
          not necessary to populate the first segment with 
          data before starting the second segment. 
       
          The file must be closed by a call to ekcls_c. 
          ./
          ekcls_c ( handle ); 
       }

 
-Restrictions
 
   1)  Only one segment can be created at a time using the fast 
       write routines. 
 
   2)  No other EK operation may interrupt a fast write.  For 
       example, it is not valid to issue a query while a fast write 
       is in progress. 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman   (JPL) 
 
-Version

   -CSPICE Version 1.2.2, 14-AUG-2006   (EDW)

      Replace mention of ldpool_c with furnsh_c.

   -CSPICE Version 1.2.1, 09-JAN-2002 (NJB)

      Documentation change:  instances of the phrase "fast load"
      were replaced with "fast write."

      Const-qualified input array cvals.

   -CSPICE Version 1.1.0, 12-JUL-1998 (NJB)

       Bug fix:  now counts elements rather than rows for vector-valued
       columns.
       
       Bug fix:  now uses dynamically allocated array of type logical
       to interface with underlying f2c'd function ekaclc_.
       
       Now maps segno from C to Fortran range.
       
       Added "undef" of masking macro.  Changed input pointer types
       to pointers to const objects.
       
       Replaced eksdsc_ call with ekssum_c call.  This removes unsightly
       references to segment descriptor alignments.
       
       Fixed some chkout_c calls which referenced ekifld_c.
       
   -CSPICE Version 1.0.0, 25-FEB-1999 (NJB)
   
      Based on SPICELIB Version 1.0.0, 08-NOV-1995 (NJB)

-Index_Entries
 
   write entire character column to EK segment 
 
-&
*/

{ /* Begin ekaclc_c */


   /*
   Local variables
   */
   SpiceBoolean            fnd;

   logical               * logicalFlags;
   
   SpiceEKSegSum           summary;
   
   SpiceChar            ** cvalsPtr;
   SpiceChar             * fCvalsArr;

   SpiceInt                i;
   SpiceInt                fCvalsLen;
   SpiceInt                fSegno;
   SpiceInt                ncols;
   SpiceInt                nelts;
   SpiceInt                nrows;
   SpiceInt                size;



   /*
   Participate in error tracing.
   */
   chkin_c ( "ekaclc_c" );


   /*
   Check the column name to make sure the pointer is non-null 
   and the string length is non-zero.
   */
   CHKFSTR ( CHK_STANDARD, "ekaclc_c", column );


   /*
   Check the value array to make sure the pointer is non-null 
   and the string length is non-zero.  Note:  this check is normally
   done for output strings:  CHKOSTR is the macro that does the job.
   */
   CHKOSTR ( CHK_STANDARD, "ekaclc_c", cvals, vallen );


   /*
   Get the row count for this segment.
   */ 
   ekssum_c ( handle, segno, &summary );
   
   nrows = summary.nrows;
   

   /*
   Locate the index of this column in the segment descriptor.
   */
   ncols = summary.ncols;
   i     = 0;
   fnd   = SPICEFALSE;
   
   while (  ( i < ncols ) && ( !fnd ) )
   {
      if (  eqstr_c( column, summary.cnames[i] )  )
      {
         fnd = SPICETRUE;
      }
      else
      {
         i++;
      }
   }
   
   
   if ( !fnd )
   {
      setmsg_c ( "Column <#> does not belong to segment #. "  );
      errch_c  ( "#",  column                                 );
      errint_c ( "#",  segno                                  );
      sigerr_c ( "SPICE(NOCOLUMN)"                            );
      chkout_c ( "ekaclc_c"                                   );
      return;
   }
   
   
   /*
   Now i is the index within the segment descriptor of the column
   descriptor for the column of interest.  Get the dimension information
   for this column.
   */
   size = summary.cdescrs[i].size;
   
   
   /*
   Compute the total string count of the input array.  If the column
   has fixed-size entries, we ignore the entszs array.  Otherwise, the
   entszs array tells us how many strings we're getting.
   */
   
   if ( size == SPICE_EK_VARSIZ )
   {
      nelts = sumai_c ( entszs, nrows );
   }
   else
   {
      nelts = nrows * size;
   }
   
   
   /*
   Allocate an array of logicals and assign values from the input
   array of SpiceBooleans.
   */
   logicalFlags = ( logical * ) malloc ( nelts * sizeof(logical) );

   if ( !logicalFlags )
   {
      setmsg_c ( "Failure on malloc call to create null flag array "
                 "for column values."                              );
      sigerr_c ( "SPICE(MALLOCFAILED)"                             );
      chkout_c ( "ekaclc_c"                                        );
      return;
   }
      
      
   /*
   Copy the input null flags to our array of type logical.
   */
   for ( i = 0;  i < nrows;  i++ )
   {
      logicalFlags[i] = nlflgs[i];
   }


   /*
   We need to make a blank-padded version of the cvals array.
   We'll first allocate an array of character pointers to index
   the values, initialize this array, and use it to produce
   a dynamically allocated array of Fortran-style strings.
   */
   
   cvalsPtr = ( SpiceChar ** ) malloc ( nelts * sizeof(SpiceChar *) );

   if ( cvalsPtr == 0 )
   {
      free ( logicalFlags );
      
      
      setmsg_c ( "Failure on malloc call to create pointer array "
                 "for column values."                              );
      sigerr_c ( "SPICE(MALLOCFAILED)"                             );
      chkout_c ( "ekaclc_c"                                        );
      return;
   }
   
   for ( i = 0;  i < nelts;  i++  )
   {
      cvalsPtr[i] =  (SpiceChar *)cvals  +  ( i * vallen );
   }
   
   C2F_CreateFixStrArr (  nelts, 
                          vallen,
                          ( ConstSpiceChar ** ) cvalsPtr, 
                          &fCvalsLen, 
                          &fCvalsArr                      );
   
   if ( failed_c() )
   {
      free ( logicalFlags );
      free ( cvalsPtr     );
      
      chkout_c ( "ekaclc_c" );
      return;
   }

   /*
   Map the segment number to the Fortran range.
   */
   fSegno = segno + 1;
   
   
   ekaclc_ ( ( integer    * ) &handle,
             ( integer    * ) &fSegno,
             ( char       * ) column,
             ( char       * ) fCvalsArr,
             ( integer    * ) entszs,
             ( logical    * ) logicalFlags,
             ( integer    * ) rcptrs,
             ( integer    * ) wkindx,
             ( ftnlen       ) strlen(column),
             ( ftnlen       ) fCvalsLen        );


   /*
   Clean up all of our dynamically allocated arrays.
   */
   free ( cvalsPtr     );
   free ( fCvalsArr    );
   free ( logicalFlags );
   

   chkout_c ( "ekaclc_c" );

} /* End ekaclc_c */
Ejemplo n.º 16
0
//------------------------------------------------------------------------------
void  SpiceAttitudeKernelReader::GetCoverageStartAndEnd(StringArray       &kernels,
                                                        Integer           forNaifId,
                                                        Real              &start,
                                                        Real              &end,
                                                        bool              needAngVel)
{
   // first check to see if a kernel specified is not loaded; if not,
   // try to load it
   for (unsigned int ii = 0; ii < kernels.size(); ii++)
      if (!IsLoaded(kernels.at(ii)))   LoadKernel(kernels.at(ii));

   SpiceInt         idSpice     = forNaifId;
   SpiceInt         arclen      = 4;
   SpiceInt         typlen      = 5;
   bool             firstInt    = true;
   bool             idOnKernel  = false;
   char             kStr[5]     = "    ";
   char             aStr[4]     = "   ";
   char             levelStr[8] = "SEGMENT";
   char             timeStr[4]  = "TDB";
   SpiceBoolean     needAv      = needAngVel;
   ConstSpiceChar   *kernelName = NULL;
   ConstSpiceChar   *level      = levelStr;
   ConstSpiceChar   *timeSys    = timeStr;
   SpiceDouble      tol         = 0.0;
   SpiceInt         objId       = 0;
   SpiceInt         numInt      = 0;
   SpiceChar        *kernelType;
   SpiceChar        *arch;
   SpiceDouble      b;
   SpiceDouble      e;
   Real             bA1;
   Real             eA1;
   SPICEINT_CELL(ids, 200);
   SPICEDOUBLE_CELL(cover, 200000);

   // look through each kernel
   for (unsigned int ii = 0; ii < kernels.size(); ii++)
   {
      #ifdef DEBUG_CK_COVERAGE
         MessageInterface::ShowMessage(wxT("Checking coverage for ID %d on kernel %s\n"),
               forNaifId, (kernels.at(ii)).c_str());
      #endif
      kernelName = kernels[ii].char_str();
      // check the type of kernel
      arch        = aStr;
      kernelType  = kStr;
      getfat_c(kernelName, arclen, typlen, arch, kernelType);
      if (failed_c())
      {
         ConstSpiceChar option[] = "LONG";
         SpiceInt       numChar  = MAX_LONG_MESSAGE_VALUE;
         SpiceChar      err[MAX_LONG_MESSAGE_VALUE];
         getmsg_c(option, numChar, err);
         wxString errStr(wxString::FromAscii( err));
         wxString errmsg = wxT("Error determining type of kernel \"");
         errmsg += kernels.at(ii) + wxT("\".  Message received from CSPICE is: ");
         errmsg += errStr + wxT("\n");
         reset_c();
         throw UtilityException(errmsg);
      }
      #ifdef DEBUG_CK_COVERAGE
         MessageInterface::ShowMessage(wxT("Kernel is of type %s\n"),
               kernelType);
      #endif
      // only deal with CK kernels
      if (eqstr_c(kernelType, "ck") || eqstr_c(kernelType, "CK"))
      {
         ckobj_c(kernelName, &ids);
         // get the list of objects (IDs) for which data exists in the CK kernel
         for (SpiceInt jj = 0;  jj < card_c(&ids);  jj++)
         {
            objId = SPICE_CELL_ELEM_I(&ids,jj);
            #ifdef DEBUG_CK_COVERAGE
               MessageInterface::ShowMessage(wxT("Kernel contains data for object %d\n"),
                     (Integer) objId);
            #endif
            // look to see if this kernel contains data for the object we're interested in
            if (objId == idSpice)
            {
               idOnKernel = true;
               break;
            }
//            if (objId == (idSpice * 1000))
//            {
//               idSpice     = idSpice * 1000;
//               naifIDSPICE = idSpice; // not the way to do this - should pass it back
//               idOnKernel  = true;
//               break;
//            }
         }
         // only deal with kernels containing data for the object we're interested in
         if (idOnKernel)
         {
            #ifdef DEBUG_CK_COVERAGE
               MessageInterface::ShowMessage(wxT("Checking kernel %s for data for object %d\n"),
                     (kernels.at(ii)).c_str(), (Integer) objId);
            #endif
            scard_c(0, &cover);   // reset the coverage cell
            ckcov_c (kernelName, idSpice, needAv, level, tol, timeSys, &cover);
            if (failed_c())
            {
               ConstSpiceChar option[] = "LONG";
               SpiceInt       numChar  = MAX_LONG_MESSAGE_VALUE;
               SpiceChar      err[MAX_LONG_MESSAGE_VALUE];
               getmsg_c(option, numChar, err);
               wxString errStr(wxString::FromAscii(err));
               wxString errmsg = wxT("Error determining coverage for CK kernel \"");
               errmsg += kernels.at(ii) + wxT("\".  Message received from CSPICE is: ");
               errmsg += errStr + wxT("\n");
               reset_c();
               throw UtilityException(errmsg);
            }
            numInt = wncard_c(&cover);
            #ifdef DEBUG_CK_COVERAGE
               MessageInterface::ShowMessage(wxT("Number of intervals found =  %d\n"),
                     (Integer) numInt);
            #endif
            if ((firstInt) && (numInt > 0))
            {
               wnfetd_c(&cover, 0, &b, &e);
               if (failed_c())
               {
                  ConstSpiceChar option[] = "LONG";
                  SpiceInt       numChar  = MAX_LONG_MESSAGE_VALUE;
                  SpiceChar      err[MAX_LONG_MESSAGE_VALUE];
                  getmsg_c(option, numChar, err);
                  wxString errStr(wxString::FromAscii(err));
                  wxString errmsg = wxT("Error getting interval times for CK kernel \"");
                  errmsg += kernels.at(ii) + wxT("\".  Message received from CSPICE is: ");
                  errmsg += errStr + wxT("\n");
                  reset_c();
                  throw UtilityException(errmsg);
               }
               start    = SpiceTimeToA1(b);
               end      = SpiceTimeToA1(e);
               firstInt = false;
            }
            for (SpiceInt jj = 0; jj < numInt; jj++)
            {
               wnfetd_c(&cover, jj, &b, &e);
               bA1 = SpiceTimeToA1(b);
               eA1 = SpiceTimeToA1(e);
               if (bA1 < start)  start = bA1;
               if (eA1 > end)    end   = eA1;
            }
         }

      }
   }
   if (firstInt)
   {
      char           itsName[256];
      SpiceChar      *itsNameSPICE = itsName;
      SpiceBoolean   found2;
      bodc2n_c(naifIDSPICE, 256, itsNameSPICE, &found2);
      if (found2 == SPICEFALSE)
      {
         wxString errmsg = wxT("Error - unable to find name for body in SPICE kernel pool");
         throw UtilityException(errmsg);
      }
      else
      {
         wxString nameStr = wxString::FromAscii(itsNameSPICE);
         wxString errmsg = wxT("Error - no data available for body ");
         errmsg += nameStr + wxT(" on specified CK kernels");
         throw UtilityException(errmsg);
      }
   }
}
Ejemplo n.º 17
0
//---------------------------------------------------------------------------
void SpiceAttitudeKernelReader::GetTargetOrientation(const wxString &objectName,
                                                     Integer           naifID,
                                                     Integer           forFrameNaifId,
                                                     const A1Mjd       &atTime,
//                                                     Real              tolerance,
                                                     Rmatrix33         &r33,
                                                     Rvector3          &angVel,
                                                     const wxString &referenceFrame)
{
   #ifdef DEBUG_CK_READING
      MessageInterface::ShowMessage(wxT("Entering GetTargetOrientation for object %s, with NAIF ID %d, at time %12.10f, with frame = %s\n"),
         objectName.c_str(), naifID, atTime.Get(), referenceFrame.c_str());
   #endif
   wxString objectNameToUse = objectName;

   objectNameToUse       = GmatStringUtil::ToUpper(objectNameToUse);
   objectNameSPICE       = objectNameToUse.char_str();
   naifIDSPICE           = naifID;
   frameNaifIDSPICE      = forFrameNaifId;
   referenceFrameSPICE   = referenceFrame.char_str();
   etSPICE               = A1ToSpiceTime(atTime.Get());

//   boddef_c(objectNameSPICE, naifIDSPICE);        // CSPICE method to set NAIF ID for an object - is this valid for spacecraft?
   // Convert the time (in TDB) to spacecaft ticks
   SpiceDouble scTime;
   sce2c_c(naifIDSPICE, etSPICE, &scTime);
   if (failed_c())
   {
      ConstSpiceChar option[] = "LONG"; // retrieve long error message, for now
      SpiceInt       numChar  = MAX_LONG_MESSAGE_VALUE;
      //SpiceChar      err[MAX_LONG_MESSAGE_VALUE];
      SpiceChar      *err = new SpiceChar[MAX_LONG_MESSAGE_VALUE];
      getmsg_c(option, numChar, err);
      wxString errStr(wxString::FromAscii(err));
      wxString errmsg = wxT("Error getting spacecraft time (ticks) for object \"");
      errmsg += objectName + wxT("\".  Message received from CSPICE is: ");
      errmsg += errStr + wxT("\n");
      reset_c();
      delete [] err;
      throw UtilityException(errmsg);
   }
   // get the tolerance in spacecraft clock ticks
   wxString    tolerance = wxT("01");  // this should probably be user input, or set as a constant
   ConstSpiceChar *tol = tolerance.char_str();
   SpiceDouble    tolTicks;
   sctiks_c(naifIDSPICE, tol, &tolTicks);
   if (failed_c())
   {
      ConstSpiceChar option[] = "LONG"; // retrieve long error message, for now
      SpiceInt       numChar  = MAX_LONG_MESSAGE_VALUE;
      //SpiceChar      err[MAX_LONG_MESSAGE_VALUE];
      SpiceChar      *err = new SpiceChar[MAX_LONG_MESSAGE_VALUE];
      getmsg_c(option, numChar, err);
      wxString errStr(wxString::FromAscii(err));
      wxString errmsg = wxT("Error getting tolerance (ticks) for object \"");
      errmsg += objectName + wxT("\".  Message received from CSPICE is: ");
      errmsg += errStr + wxT("\n");
      reset_c();
      delete [] err;
      throw UtilityException(errmsg);
   }
   #ifdef DEBUG_CK_READING
      MessageInterface::ShowMessage(wxT("First, check for coverage for object \"%s\", with NAIF ID %d\n"),
         objectName.c_str(), naifID);
   #endif
   Real beginCov = 0.0;
   Real endCov   = 0.0;
   GetCoverageStartAndEnd(loadedKernels, forFrameNaifId, beginCov, endCov, false);

   // Now get the C-matrix and angular velocity at the requested time
   SpiceDouble    cmat[3][3];
   SpiceDouble    av[3];
   SpiceBoolean   found;
   SpiceDouble    clkout;
   #ifdef DEBUG_CK_READING
      MessageInterface::ShowMessage(wxT("about to call ckgpav: \n"));
      MessageInterface::ShowMessage(wxT("   NAIF ID  = %d\n")
                                    wxT("   etSPICE  = %12.10f\n")
                                    wxT("   scTime   = %12.10fn")
                                    wxT("   tolTicks = %12.10f\n")
                                    wxT("   refFrame = %s\n"),
         (Integer) naifIDSPICE, (Real) etSPICE, (Real) scTime, (Real) tolTicks,
         referenceFrame.c_str());
   #endif
   ckgpav_c(frameNaifIDSPICE, scTime, tolTicks, referenceFrameSPICE, cmat, av, &clkout, &found);
//   ckgpav_c(naifIDSPICE, scTime, tolTicks, referenceFrameSPICE, cmat, av, &clkout, &found);
   if (failed_c())
   {
      ConstSpiceChar option[] = "LONG"; // retrieve long error message, for now
      SpiceInt       numChar  = MAX_LONG_MESSAGE_VALUE;
      //SpiceChar      err[MAX_LONG_MESSAGE_VALUE];
      SpiceChar      *err = new SpiceChar[MAX_LONG_MESSAGE_VALUE];
      getmsg_c(option, numChar, err);
      wxString errStr(wxString::FromAscii(err));
      wxString errmsg = wxT("Error getting C-matrix and/or angular velocity for object \"");
      errmsg += objectName + wxT("\".  Message received from CSPICE is: ");
      errmsg += errStr + wxT("\n");
      reset_c();
      delete [] err;
      throw UtilityException(errmsg);
   }
   if (found == SPICEFALSE)
   {
      wxString errmsg = wxT("Pointing data for object ");
      errmsg += objectName + wxT(" not found on loaded CK/SCLK kernels.\n");
      throw UtilityException(errmsg);
   }
   #ifdef DEBUG_CK_READING
      MessageInterface::ShowMessage(wxT("results from ckgpav: \n"));
      MessageInterface::ShowMessage(wxT("   cosMat = %12.10f  %12.10f  %12.10f\n")
                                    wxT("            %12.10f  %12.10f  %12.10f\n")
                                    wxT("            %12.10f  %12.10f  %12.10f\n"),
                                    (Real)cmat[0][0], (Real)cmat[0][1], (Real)cmat[0][2],
                                    (Real)cmat[1][0], (Real)cmat[1][1], (Real)cmat[1][2],
                                    (Real)cmat[2][0], (Real)cmat[2][1], (Real)cmat[2][2]);
      MessageInterface::ShowMessage(wxT("   angvel = %12.10f  %12.10f  %12.10f\n"),
                                   (Real)av[0], (Real)av[1], (Real)av[2]);
      MessageInterface::ShowMessage(wxT("   and clkout = %12.10f\n"), (Real) clkout);
   #endif
   // Set output values
   r33.Set(cmat[0][0], cmat[0][1], cmat[0][2],
           cmat[1][0], cmat[1][1], cmat[1][2],
           cmat[2][0], cmat[2][1], cmat[2][2]);
   angVel.Set(av[0], av[1], av[2]);

}
Ejemplo n.º 18
0
   void dasac_c ( SpiceInt       handle,
                  SpiceInt       n,
                  SpiceInt       buflen,
                  const void   * buffer  ) 

/*

-Brief_I/O
 
   Variable  I/O  Description 
   --------  ---  -------------------------------------------------- 
   handle     I   DAS handle of a file opened with write access. 
   n          I   Number of comments to put into the comment area. 
   buflen     I   Line length associated with buffer.
   buffer     I   Buffer of lines to be put into the comment area. 
 
-Detailed_Input
 
   handle   The file handle of a binary DAS file which has been 
            opened with write access. 
 
   n        The number of strings in buffer that are to be 
            appended to the comment area of the binary DAS file 
            attached to handle. 

   buflen   is the common length of the strings in buffer, including the 
            terminating nulls.
 
   buffer   A buffer containing comments which are to be added 
            to the comment area of the binary DAS file attached 
            to handle.  buffer should be declared as follows:
              
               ConstSpiceChar   buffer [n][buflen]
              
            Each string in buffer is null-terminated.
 
-Detailed_Output
 
   None. 
 
-Parameters
 
   None. 
 
-Exceptions
 
   1) If the number of comments to be added is not positive, the 
      error SPICE(INVALIDARGUMENT) will be signaled. 
 
   2) If a non-null, non printing ASCII character is encountered in the 
      comments, the error SPICE(ILLEGALCHARACTER) will be 
      signaled. 
 
   3) If the binary DAS file attached to handle is not open for 
      write access, an error will be signaled by a routine called 
      by this routine. 
 
   4) If the input buffer pointer is null, the error SPICE(NULLPOINTER) 
      will be signaled.

   5) If the input buffer string length buflen is not at least 2, 
      the error SPICE(STRINGTOOSHORT) will be signaled.

-Files
 
   See argument handle in Detailed_Input. 
 
-Particulars
 
   Binary DAS files contain a data area which is reserved for storing 
   annotations or descriptive textual information about the data 
   contained in a file. This area is referred to as the "comment 
   area" of the file. The comment area of a DAS file is a line 
   oriented medium for storing textual information. The comment 
   area preserves any leading or embedded white space in the line(s) 
   of text which are stored so that the appearance of the 
   information will be unchanged when it is retrieved (extracted) at 
   some other time. Trailing blanks, however, are NOT preserved, 
   due to the way that character strings are represented in 
   standard Fortran 77. 
 
   This routine will take a buffer of text lines and add (append) 
   them to the comment area of a binary DAS file. If there are no 
   comments in the comment area of the file, then space will be 
   allocated and the text lines in buffer will then placed into the 
   comment area. The text lines may contain only printable ASCII 
   characters (decimal values 32 - 126). 
 
   There is no maximum length imposed on the significant portion 
   of a text line that may be placed into the comment area of a 
   DAS file. The maximum length of a line stored in the comment 
   area should be reasonable, however, so that they may be easily 
   extracted. A good value for this would be 255 characters, as 
   this can easily accommodate "screen width" lines as well as 
   long lines which may contain some other form of information. 
 
-Examples
 
   Let 
 
      handle   be the handle for a DAS file which has been opened 
               with write access. 

      n        be the number of lines of text to be added to the 
               comment area of the binary DAS file attached to 
               handle. 

      BUFLEN   be the declared line length of the buffer.

      buffer   is a list of text lines to be added to the comment 
               area of the binary DAS file attached to handle. 
 
   The call 
 
      dasac_c ( handle, n, BUFLEN, buffer );
 
   will append the first n line(s) in buffer to the comment area 
   of the binary DAS file attached to handle. 
 
-Restrictions
 
   1) This routine uses constants that are specific to the ASCII 
      character sequence. The results of using this routine with 
      a different character sequence are unpredictable. 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman   (JPL) 
   K.R. Gehringer (JPL) 
 
-Version
 
   -CSPICE Version 1.1.0, 02-MAR-2003 (NJB) 

       Added error check in wrapper for non-positive
       buffer line count.

   -CSPICE Version 1.0.0, 25-FEB-2003 (NJB) (KRG)

-Index_Entries
 
    add comments to a binary das file 
    append comments to a das file comment area 
 
-&
*/

{ /* Begin dasac_c */


   /*
   Local variables
   */

   SpiceChar             * fCvalsArr;

   SpiceInt                fCvalsLen;


   /*
   Participate in error tracing.
   */
   if ( return_c() )
   {
      return;
   }
   chkin_c ( "dasac_c" );

   /*
   Check the line count of the input buffer. 
   */
   if ( n < 1 ) 
   {
      setmsg_c ( "Comment buffer line count n = #; must be positive." );
      errint_c ( "#", n                                               );
      sigerr_c ( "SPICE(INVALIDARGUMENT)"                             );
      chkout_c ( "dasac_c"                                            );
      return;
   }

   /*
   Check the input buffer for null pointer or short lines. 
   */
   CHKOSTR ( CHK_STANDARD, "dasac_c", buffer, buflen );


   /*
   Map the input buffer to a Fortran-style buffer. 
   */
   C2F_MapStrArr ( "dasac_c", n, buflen, buffer, &fCvalsLen, &fCvalsArr );

   if ( failed_c() )
   {
      chkout_c ( "dasac_c" );
      return;
   }


   /*
   Call the f2c'd routine.
   */
   dasac_ (  ( integer    * ) &handle,
             ( integer    * ) &n,
             ( char       * ) fCvalsArr,
             ( ftnlen       ) fCvalsLen );


   /*
   Free the dynamically allocated array.
   */
   free ( fCvalsArr );


   chkout_c ( "dasac_c" );

} /* End dasac_c */
Ejemplo n.º 19
0
   void gfsubc_c ( ConstSpiceChar     * target,
                   ConstSpiceChar     * fixref,
                   ConstSpiceChar     * method,
                   ConstSpiceChar     * abcorr,
                   ConstSpiceChar     * obsrvr,
                   ConstSpiceChar     * crdsys,
                   ConstSpiceChar     * coord,
                   ConstSpiceChar     * relate,
                   SpiceDouble          refval,
                   SpiceDouble          adjust,
                   SpiceDouble          step,
                   SpiceInt             nintvls,
                   SpiceCell          * cnfine,
                   SpiceCell          * result  )

/*

-Brief_I/O
 
   Variable  I/O  Description 
   --------  ---  --------------------------------------------------
   SPICE_GF_CNVTOL     
              P   Convergence tolerance. 
   target     I   Name of the target body
   fixref     I   Body fixed frame associated with 'target'
   method     I   Name of method type for subpoint calculation
   abcorr     I   Aberration correction flag
   obsrvr     I   Name of the observing body
   crdsys     I   Name of the coordinate system containing 'coord'
   coord      I   Name of the coordinate of interest
   relate     I   Operator that either looks for an extreme value
                  (max, min, local, absolute) or compares the
                  coordinate value and refval
   refval     I   Reference value
   adjust     I   Adjustment value for absolute extrema searches
   step       I   Step size used for locating extrema and roots
   nintvls    I   Workspace window interval count
   cnfine    I-O  SPICE window to which the search is restricted
   result     O   SPICE window containing results

-Detailed_Input

   target     the string name of a target body.  Optionally, you may
              supply the integer ID code for the object as an
              integer string.  For example both 'MOON' and '301'
              are legitimate strings that indicate the moon is the
              target body.

              The target and observer define a position vector
              that points from the observer to the target.

   fixref     the string name of the body-fixed, body-centered
              reference frame associated with the target body target.

              The SPICE frame subsystem must recognize the 'fixref' name.

   method     the string name of the method to use for the subpoint
              calculation. The accepted values for method:

                 'Near point: ellipsoid'   The sub-observer point
                                           computation uses a
                                           triaxial ellipsoid to
                                           model the surface of the
                                           target body. The
                                           sub-observer point is
                                           defined as the nearest
                                           point on the target
                                           relative to the
                                           observer. 

                 'Intercept: ellipsoid'    The sub-observer point
                                           computation uses a
                                           triaxial ellipsoid to
                                           model the surface of the
                                           target body. The
                                           sub-observer point is
                                           defined as the target
                                           surface intercept of the
                                           line containing the
                                           observer and the
                                           target's center.

              The method string lacks sensitivity to case, embedded, leading 
              and trailing blanks.

   abcorr     the string description of the aberration corrections to apply
              to the state evaluations to account for one-way light time
              and stellar aberration.

              This routine accepts the same aberration corrections as does 
              the SPICE routine SPKEZR. See the header of SPKEZR for a
              detailed description of the aberration correction options.
              For convenience, the options are listed below:

                  'NONE'     Apply no correction.   

                  'LT'       "Reception" case:  correct for
                             one-way light time using a Newtonian
                             formulation.

                  'LT+S'     "Reception" case:  correct for
                             one-way light time and stellar
                             aberration using a Newtonian
                             formulation.

                  'CN'       "Reception" case:  converged
                             Newtonian light time correction.

                  'CN+S'     "Reception" case:  converged
                             Newtonian light time and stellar
                             aberration corrections.

                  'XLT'      "Transmission" case:  correct for
                             one-way light time using a Newtonian
                             formulation.

                  'XLT+S'    "Transmission" case:  correct for
                             one-way light time and stellar
                             aberration using a Newtonian
                             formulation.

                  'XCN'      "Transmission" case:  converged
                             Newtonian light time correction.

                  'XCN+S'    "Transmission" case:  converged
                             Newtonian light time and stellar
                             aberration corrections.

              The abcorr string lacks sensitivity to case, and to embedded, 
              leading and trailing blanks.

     obsrvr   the string naming the observing body. Optionally, you
              may supply the ID code of the object as an integer
              string. For example, both 'EARTH' and '399' are
              legitimate strings to supply to indicate the
              observer is Earth.

     crdsys   the string name of the coordinate system for which the
              coordinate of interest is a member.

     coord    the string name of the coordinate of interest in crdsys.
                            
              The supported coordinate systems and coordinate names are:

              The supported coordinate systems and coordinate names are:

              Coordinate System (CRDSYS)    Coordinates (COORD)      Range

                 'RECTANGULAR'                  'X'
                                                'Y'
                                                'Z'

                 'LATITUDINAL'                  'RADIUS'
                                                'LONGITUDE'        (-Pi,Pi]
                                                'LATITUDE'         [-Pi/2,Pi/2]

                 'RA/DEC'                       'RANGE'
                                                'RIGHT ASCENSION'  [0,2Pi)
                                                'DECLINATION'      [-Pi/2,Pi/2]

                 'SPHERICAL'                    'RADIUS'
                                                'COLATITUDE'       [0,Pi]
                                                'LONGITUDE'        (-Pi,Pi]

                 'CYLINDRICAL'                  'RADIUS'
                                                'LONGITUDE'        [0,2Pi)
                                                'Z'

                 'GEODETIC'                     'LONGITUDE'        (-Pi,Pi]
                                                'LATITUDE'         [-Pi/2,Pi/2]
                                                'ALTITUDE' 

                 'PLANETOGRAPHIC'               'LONGITUDE'        [0,2Pi)
                                                'LATITUDE'         [-Pi/2,Pi/2]
                                                'ALTITUDE'

                  The ALTITUDE coordinates have a constant value
                  of zero +/- roundoff for ellipsoid targets.

                  Limit searches for coordinate events in the GEODETIC and 
                  PLANETOGRAPHIC coordinate systems to TARGET bodies with
                  axial symmetry in the equatorial plane, i.e. equality
                  of the body X and Y radii (oblate or prolate spheroids).

     relate    the string or character describing the relational operator 
               used to define a constraint on the selected coordinate of the 
               subpoint vector. The result window found by this routine 
               indicates the time intervals where the constraint is satisfied.
               Supported values of relate and corresponding meanings are
               shown below:

                  '>'      Separation is greater than the reference
                           value refval.

                  '='      Separation is equal to the reference
                           value refval.

                  '<'      Separation is less than the reference
                           value refval.

                 'ABSMAX'  Separation is at an absolute maximum.

                 'ABSMIN'  Separation is at an absolute  minimum.

                 'LOCMAX'  Separation is at a local maximum.

                 'LOCMIN'  Separation is at a local minimum.

              The caller may indicate that the region of interest
              is the set of time intervals where the quantity is
              within a specified measure of an absolute extremum.
              The argument ADJUST (described below) is used to
              specify this measure.

              Local extrema are considered to exist only in the
              interiors of the intervals comprising the confinement
              window:  a local extremum cannot exist at a boundary
              point of the confinement window.

              The relate string lacks sensitivity to case, leading 
              and trailing blanks.

   refval     the double precision reference value used together with
              relate argument to define an equality or inequality to
              satisfy by the selected coordinate of the subpoint
              vector. See the discussion of relate above for
              further information.

              The units of refval correspond to the type as defined
              by coord, radians for angular measures, kilometers for
              distance measures.

   adjust     a double precision value used to modify searches for
              absolute extrema: when 'relate' is set to ABSMAX or ABSMIN and
              'adjust' is set to a positive value, gfsubc_c finds times 
              when the position vector coordinate is within adjust 
              radians/kilometers of the specified extreme value.

              For 'relate' set to ABSMAX, the result window contains
              time intervals when the position vector coordinate has
              values between ABSMAX - adjust and ABSMAX.

              For 'relate' set to ABSMIN, the result window contains
              time intervals when the position vector coordinate has
              values between ABSMIN and ABSMIN + adjust.
               
              'adjust' is not used for searches for local extrema,
              equality or inequality conditions.

   step       the double precision time step size to use in the search.
              step must be short enough for a search using this step
              size to locate the time intervals where coordinate function
              of the subpoint vector is monotone increasing or
              decreasing. However, step must not be *too* short, or
              the search will take an unreasonable amount of time.

              The choice of step affects the completeness but not
              the precision of solutions found by this routine; the
              precision is controlled by the convergence tolerance.

              step has units of TDB seconds. 

   nintvls    an integer value specifying the number of intervals in the 
              the internal workspace array used by this routine. 'nintvls'
              should be at least as large as the number of intervals
              within the search region on which the specified observer-target
              vector coordinate function is monotone increasing or decreasing. 
              It does no harm to pick a value of 'nintvls' larger than the
              minimum required to execute the specified search, but if chosen 
              too small, the search will fail.

   cnfine     a double precision SPICE window that confines the time
              period over which the specified search is conducted.
              cnfine may consist of a single interval or a collection
              of intervals. 

              In some cases the confinement window can be used to
              greatly reduce the time period that must be searched
              for the desired solution. See the Particulars section
              below for further discussion.
              
              See the Examples section below for a code example 
              that shows how to create a confinement window.
               
-Detailed_Output

   cnfine     is the input confinement window, updated if necessary
              so the control area of its data array indicates the
              window's size and cardinality. The window data are
              unchanged.

   result     the SPICE window of intervals, contained within the
              confinement window cnfine, on which the specified
              constraint is satisfied.
 
              If result is non-empty on input, its contents
              will be discarded before gfsubc_c conducts its
              search.
              
              result must be declared and initialized with sufficient
              size to capture the full set of time intervals 
              within the search region on which the specified constraint 
              is satisfied.
              
              If the search is for local extrema, or for absolute
              extrema with adjust set to zero, then normally each
              interval of result will be a singleton: the left and
              right endpoints of each interval will be identical.
 
              If no times within the confinement window satisfy the
              constraint, result will be returned with a
              cardinality of zero.

-Parameters
 
   SPICE_GF_CNVTOL     

              is the convergence tolerance used for finding endpoints
              of the intervals comprising the result window.
              SPICE_GF_CNVTOL is used to determine when binary searches
              for roots should terminate: when a root is bracketed
              within an interval of length SPICE_GF_CNVTOL; the root is
              considered to have been found.
 
              The accuracy, as opposed to precision, of roots found by
              this routine depends on the accuracy of the input data.
              In most cases, the accuracy of solutions will be inferior
              to their precision.
 
              SPICE_GF_CNVTOL has the value 1.0e-6. Units are TDB
              seconds.

-Exceptions

   1)  In order for this routine to produce correct results, 
       the step size must be appropriate for the problem at hand. 
       Step sizes that are too large may cause this routine to miss 
       roots; step sizes that are too small may cause this routine 
       to run unacceptably slowly and in some cases, find spurious 
       roots. 
 
       This routine does not diagnose invalid step sizes, except 
       that if the step size is non-positive, an error is signaled 
       by a routine in the call tree of this routine. 
 
   2)  Due to numerical errors, in particular, 
 
          - Truncation error in time values 
          - Finite tolerance value 
          - Errors in computed geometric quantities 
 
       it is *normal* for the condition of interest to not always be 
       satisfied near the endpoints of the intervals comprising the 
       result window. 
 
       The result window may need to be contracted slightly by the 
       caller to achieve desired results. The SPICE window routine 
       wncond_c can be used to contract the result window. 
 
   3)  If an error (typically cell overflow) occurs while performing  
       window arithmetic, the error will be diagnosed by a routine 
       in the call tree of this routine. 
 
   4)  If the relational operator `relate' is not recognized, an  
       error is signaled by a routine in the call tree of this 
       routine. 
 
   5)   If the aberration correction specifier contains an
        unrecognized value, an error is signaled by a routine in the
        call tree of this routine.
 
   6)  If `adjust' is negative, an error is signaled by a routine in 
       the call tree of this routine. 
 
   7)  If either of the input body names do not map to NAIF ID 
       codes, an error is signaled by a routine in the call tree of 
       this routine. 
 
   8)  If required ephemerides or other kernel data are not 
       available, an error is signaled by a routine in the call tree 
       of this routine. 
 
   9)  If any input string argument pointer is null, the error
       SPICE(NULLPOINTER) will be signaled.

   10) If any input string argument is empty, the error 
       SPICE(EMPTYSTRING) will be signaled.

   11) If the workspace interval count 'nintvls' is less than 1, the
       error SPICE(VALUEOUTOFRANGE) will be signaled.

   12) If the required amount of workspace memory cannot be
       allocated, the error SPICE(MALLOCFAILURE) will be
       signaled.
              
-Files

   Appropriate SPK and PCK kernels must be loaded by the
   calling program before this routine is called.

   The following data are required:

      - SPK data: the calling application must load ephemeris data
        for the targets, observer, and any intermediate objects in 
        a chain connecting the targets and observer that cover the time
        period specified by the window CNFINE. If aberration
        corrections are used, the states of target and observer
        relative to the solar system barycenter must be calculable
        from the available ephemeris data. Typically ephemeris data
        are made available by loading one or more SPK files using
        FURNSH.

      - PCK data: bodies modeled as triaxial ellipsoids must have
        semi-axis lengths provided by variables in the kernel pool.
        Typically these data are made available by loading a text
        PCK file using FURNSH.

      - If non-inertial reference frames are used, then PCK
        files, frame kernels, C-kernels, and SCLK kernels may be
        needed.

   Such kernel data are normally loaded once per program
   run, NOT every time this routine is called. 

-Particulars


   This routine provides a simpler, but less flexible interface
   than does the routine gfevnt_c for conducting searches for
   subpoint position vector coordinate value events. 
   Applications that require support for progress reporting, interrupt 
   handling, non-default step or refinement functions, or non-default 
   convergence tolerance should call gfevnt_c rather than this routine.

   This routine determines a set of one or more time intervals
   within the confinement window when the selected coordinate of 
   the subpoint position vector satisfies a caller-specified
   constraint. The resulting set of intervals is returned as a SPICE
   window.

   Below we discuss in greater detail aspects of this routine's
   solution process that are relevant to correct and efficient
   use of this routine in user applications.

   The Search Process
   ==================

   Regardless of the type of constraint selected by the caller, this
   routine starts the search for solutions by determining the time
   periods, within the confinement window, over which the specified
   coordinate function is monotone increasing and monotone
   decreasing. Each of these time periods is represented by a SPICE
   window. Having found these windows, all of the coordinate
   function's local extrema within the confinement window are known.
   Absolute extrema then can be found very easily. 

   Within any interval of these "monotone" windows, there will be at
   most one solution of any equality constraint. Since the boundary
   of the solution set for any inequality constraint is the set 
   of points where an equality constraint is met, the solutions of
   both equality and inequality constraints can be found easily
   once the monotone windows have been found.


   Step Size
   =========

   The monotone windows (described above) are found using a two-step
   search process. Each interval of the confinement window is
   searched as follows: first, the input step size is used to
   determine the time separation at which the sign of the rate of
   change of coordinate will be sampled. Starting at
   the left endpoint of an interval, samples will be taken at each
   step. If a change of sign is found, a root has been bracketed; at
   that point, the time at which the time derivative of the coordinate 
   is zero can be found by a refinement process, for example,
   using a binary search.

   Note that the optimal choice of step size depends on the lengths
   of the intervals over which the coordinate function is monotone:
   the step size should be shorter than the shortest of these
   intervals (within the confinement window).

   The optimal step size is *not* necessarily related to the lengths
   of the intervals comprising the result window. For example, if
   the shortest monotone interval has length 10 days, and if the
   shortest result window interval has length 5 minutes, a step size
   of 9.9 days is still adequate to find all of the intervals in the
   result window. In situations like this, the technique of using
   monotone windows yields a dramatic efficiency improvement over a
   state-based search that simply tests at each step whether the
   specified constraint is satisfied. The latter type of search can
   miss solution intervals if the step size is shorter than the
   shortest solution interval.

   Having some knowledge of the relative geometry of the target and
   observer can be a valuable aid in picking a reasonable step size.
   In general, the user can compensate for lack of such knowledge by
   picking a very short step size; the cost is increased computation
   time.

   Note that the step size is not related to the precision with which
   the endpoints of the intervals of the result window are computed.
   That precision level is controlled by the convergence tolerance.

   Convergence Tolerance
   =====================

   As described above, the root-finding process used by this routine
   involves first bracketing roots and then using a search process
   to locate them. "Roots" are both times when local extrema are
   attained and times when the distance function is equal to a
   reference value. All endpoints of the intervals comprising the
   result window are either endpoints of intervals of the
   confinement window or roots.

   Once a root has been bracketed, a refinement process is used to
   narrow down the time interval within which the root must lie.
   This refinement process terminates when the location of the root
   has been determined to within an error margin called the
   "convergence tolerance." The convergence tolerance used by this
   routine is set by the parameter SPICE_GF_CNVTOL.

   The value of SPICE_GF_CNVTOL is set to a "tight" value in the f2c'd 
   routine so that the tolerance doesn't become the limiting factor 
   in the accuracy of solutions found by this routine. In general the 
   accuracy of input data will be the limiting factor.

   To use a different tolerance value, a lower-level GF routine such
   as gfevnt_c must be called. Making the tolerance tighter than
   SPICE_GF_CNVTOL is unlikely to be useful, since the results are unlikely
   to be more accurate. Making the tolerance looser will speed up
   searches somewhat, since a few convergence steps will be omitted.
   However, in most cases, the step size is likely to have a much
   greater effect on processing time than would the convergence
   tolerance.

   The Confinement Window
   ======================

   The simplest use of the confinement window is to specify a time
   interval within which a solution is sought. However, the
   confinement window can, in some cases, be used to make searches
   more efficient. Sometimes it's possible to do an efficient search
   to reduce the size of the time period over which a relatively
   slow search of interest must be performed.

   Practical use of the coordinate search capability would likely
   consist of searches over multiple coordinate constraints to find
   time intervals that satisfies the constraints. An effective 
   technique to accomplish such a search is to use the result
   window from one search as the confinement window of the next.

   Longitude and Right Ascension
   =============================

   The cyclic nature of the longitude and right ascension coordinates
   produces branch cuts at +/- 180 degrees longitude and 0-360
   longitude. Round-off error may cause solutions near these branches
   to cross the branch. Use of the SPICE routine wncond_c will contract
   solution windows by some epsilon, reducing the measure of the
   windows and eliminating the branch crossing. A one millisecond
   contraction will in most cases eliminate numerical round-off caused
   branch crossings.

-Examples
 
   The numerical results shown for these examples may differ across
   platforms. The results depend on the SPICE kernels used as
   input, the compiler and supporting libraries, and the machine
   specific arithmetic implementation.

   The example shown below requires a "standard" set of SPICE
   kernels. We list these kernels in a meta kernel named 'standard.tm'.
   
      KPL/MK

            This meta-kernel is intended to support operation of SPICE
            example programs. The kernels shown here should not be
            assumed to contain adequate or correct versions of data
            required by SPICE-based user applications.

            In order for an application to use this meta-kernel, the
            kernels referenced here must be present in the user's
            current working directory.

            The names and contents of the kernels referenced
            by this meta-kernel are as follows:

               File name                     Contents
               ---------                     --------
               de414.bsp                     Planetary ephemeris
               pck00008.tpc                  Planet orientation and
                                             radii
               naif0008.tls                  Leapseconds
   

      \begindata

      KERNELS_TO_LOAD = ( '/kernels/gen/lsk/naif0008.tls'
                          '/kernels/gen/spk/de414.bsp'
                          '/kernels/gen/pck/pck00008.tpc' 
                        )


      Example:

      Find the time during 2007 for which the subpoint position vector
      of the sun on earth in the IAU_EARTH frame lies within a geodetic
      latitude-longitude "box" defined as

         16 degrees <= latitude  <= 17 degrees
         85 degrees <= longitude <= 86 degrees

      This problem requires four searches, each search on one of the
      box restrictions. The user needs also realize the temporal 
      behavior of latitude greatly differs from that of the longitude. The
      sub-observer point latitude varies between approximately 23.44 degrees
      and -23.44 degrees during the year. The sub-observer point longitude 
      varies between -180 degrees and 180 degrees in one day.

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>

      #include "SpiceUsr.h"

      #define   MAXWIN   100
      #define   TIMFMT   "YYYY-MON-DD HR:MN:SC.###### (TDB) ::TDB ::RND"
      #define   STRLEN   64

      int main( int argc, char **argv )
         {

         /.
         Create the needed windows. Note, one window
         consists of two values, so the total number
         of cell values to allocate equals twice
         the number of intervals.
         ./
         SPICEDOUBLE_CELL ( result1, 2*MAXWIN );
         SPICEDOUBLE_CELL ( result2, 2*MAXWIN );
         SPICEDOUBLE_CELL ( result3, 2*MAXWIN );
         SPICEDOUBLE_CELL ( result4, 2*MAXWIN );
         SPICEDOUBLE_CELL ( cnfine, 2       );

         SpiceDouble       begtim;
         SpiceDouble       endtim;
         SpiceDouble       step;
         SpiceDouble       adjust;
         SpiceDouble       refval;
         SpiceDouble       beg;
         SpiceDouble       end;

         SpiceChar         begstr [ STRLEN ];
         SpiceChar         endstr [ STRLEN ];
         SpiceChar       * target = "EARTH";
         SpiceChar       * obsrvr = "SUN";
         SpiceChar       * fixref = "IAU_EARTH";
         SpiceChar       * method = "Near point: ellipsoid";
         SpiceChar       * crdsys = "GEODETIC";
         SpiceChar       * abcorr = "NONE";
   
         SpiceInt          count;
         SpiceInt          i;

         /.  
         Load kernels.
         ./
         furnsh_c( "standard.tm" );
   
         /.  
         Store the time bounds of our search interval in
         the cnfine confinement window.
         ./
         str2et_c( "2007 JAN 01", &begtim );
         str2et_c( "2008 JAN 01", &endtim );
   
         wninsd_c ( begtim, endtim, &cnfine );
      
         /.
         Perform four searches to determine the times when the 
         latitude-longitude box restriction conditions apply to 
         the subpoint vector.
      
         Perform the searches such that the result window of a search
         serves as the confinement window of the subsequent search.
   
         Since the latitude coordinate varies slowly and is well behaved 
         over the time of the confinement window, search first for the
         windows satisfying the latitude requirements, then use that result
         as confinement for the longitude search.
         ./
      
         /.  
         The latitude varies relatively slowly, ~46 degrees during the 
         year. The extrema occur approximately every six months.
         Search using a step size less than half that value (180 days).
         For this example use ninety days (in units of seconds).
         ./

         step   = (90.)*spd_c();
         adjust = 0.;
      
         {
         SpiceChar       * coord  = "LATITUDE";
         SpiceChar       * relate = ">";

         refval = 16. *rpd_c();

         gfsubc_c (  target,  fixref,
                     method,  abcorr, obsrvr,
                     crdsys,  coord,
                     relate,  refval,
                     adjust,  step, 
                     MAXWIN,
                     &cnfine, &result1 );
         }


         {
         SpiceChar       * coord  = "LATITUDE";
         SpiceChar       * relate = "<";

         refval = 17. *rpd_c();

         gfsubc_c (  target,  fixref,
                     method,  abcorr, obsrvr,
                     crdsys,  coord,
                     relate,  refval,
                     adjust,  step, 
                     MAXWIN,
                     &result1, &result2 );
         }


         /.
         Now the longitude search.
         ./

         /.
         Reset the stepsize to something appropriate for the 360
         degrees in 24 hours domain. The longitude shows near
         linear behavior so use a stepsize less than half the period
         of twelve hours. Ten hours will suffice in this case.
         ./
         step   = (10./24.)*spd_c();
      
         {
         SpiceChar       * coord  = "LONGITUDE";
         SpiceChar       * relate = ">";

         refval = 85. *rpd_c();

         gfsubc_c (  target,  fixref,
                     method,  abcorr, obsrvr,
                     crdsys,  coord,
                     relate,  refval,
                     adjust,  step, 
                     MAXWIN,
                     &result2, &result3 );

         /.
         Contract the endpoints of each window to account
         for possible round-off error at the -180/180 degree branch.
 
         A contraction value of a millisecond should eliminate
         any round-off caused branch crossing.
         ./
 
         wncond_c( 1e-3, 1e-3, &result3 );
         }


         {
         SpiceChar       * coord  = "LONGITUDE";
         SpiceChar       * relate = "<";

         refval = 86. *rpd_c();

         gfsubc_c (  target,  fixref,
                     method,  abcorr, obsrvr,
                     crdsys,  coord,
                     relate,  refval,
                     adjust,  step, 
                     MAXWIN,
                     &result3, &result4 );
         }


         /.  
         List the beginning and ending points in each interval
         if result contains data.
         ./
         count = wncard_c( &result4 );

         /.
         Display the results.
         ./
         if (count == 0 ) 
            {
            printf ( "Result window is empty.\n\n" );
            }
         else
            {
            for ( i = 0;  i < count;  i++ )
               {

               /.
               Fetch the endpoints of the Ith interval
               of the result window.
               ./
               wnfetd_c ( &result4, i, &beg, &end );

               timout_c ( beg, TIMFMT, STRLEN, begstr ); 
               timout_c ( end, TIMFMT, STRLEN, endstr );

               printf ( "Interval %d\n", i + 1);
               printf ( "Beginning TDB %s \n",   begstr );
               printf ( "Ending TDB    %s \n\n", endstr );

               }
            }
            
         kclear_c();
         return( 0 );
         }
   
      The program outputs:

         Interval 1
         Beginning TDB 2007-MAY-05 06:14:04.637735 (TDB) 
         Ending TDB    2007-MAY-05 06:18:04.621908 (TDB) 

         Interval 2
         Beginning TDB 2007-MAY-06 06:13:59.583483 (TDB) 
         Ending TDB    2007-MAY-06 06:17:59.569239 (TDB) 

         Interval 3
         Beginning TDB 2007-MAY-07 06:13:55.102939 (TDB) 
         Ending TDB    2007-MAY-07 06:17:55.090299 (TDB) 

         Interval 4
         Beginning TDB 2007-MAY-08 06:13:51.202604 (TDB) 
         Ending TDB    2007-MAY-08 06:17:51.191583 (TDB) 

         Interval 5
         Beginning TDB 2007-AUG-06 06:23:17.282927 (TDB) 
         Ending TDB    2007-AUG-06 06:27:17.264009 (TDB) 

         Interval 6
         Beginning TDB 2007-AUG-07 06:23:10.545441 (TDB) 
         Ending TDB    2007-AUG-07 06:27:10.524926 (TDB) 

         Interval 7
         Beginning TDB 2007-AUG-08 06:23:03.233996 (TDB) 
         Ending TDB    2007-AUG-08 06:27:03.211889 (TDB) 

-Restrictions
 
   1) The kernel files to be used by this routine must be loaded 
      (normally via the CSPICE routine furnsh_c) before this routine 
      is called. 
 
   2) This routine has the side effect of re-initializing the
      coordinate quantity utility package.  Callers may 
      need to re-initialize the package after calling this routine.
 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman   (JPL) 
   E.D. Wright    (JPL) 
 
-Version

   -CSPICE Version 1.0.1, 26-AUG-2009, EDW (JPL)

      Edit to Example description, replaced "intercept" with
      "sub-observer point."
      
      Correction of several typos.
      
   -CSPICE Version 1.0.0, 10-FEB-2009 (NJB) (EDW)

-Index_Entries

   GF subpoint coordinate search

-&
*/

   { /* Begin gfsubc_c */

   /*
   Local variables 
   */   
   doublereal            * work;

   SpiceInt                nBytes;
   
   static SpiceInt         nw = SPICE_GF_NWMAX;


   
   /*
   Participate in error tracing.
   */
   if ( return_c() )
      {
      return;
      }
   chkin_c ( "gfsubc_c" );


   /*
   Make sure cell data types are d.p. 
   */
   CELLTYPECHK2 ( CHK_STANDARD, "gfsubc_c", SPICE_DP, cnfine, result );
   
   /* 
   Initialize the input cells if necessary. 
   */
   CELLINIT2 ( cnfine, result );

   /*
   Check the input strings to make sure each pointer is non-null 
   and each string length is non-zero.
   */
   CHKFSTR ( CHK_STANDARD, "gfsubc_c", target );
   CHKFSTR ( CHK_STANDARD, "gfsubc_c", fixref );
   CHKFSTR ( CHK_STANDARD, "gfsubc_c", method );
   CHKFSTR ( CHK_STANDARD, "gfsubc_c", abcorr );
   CHKFSTR ( CHK_STANDARD, "gfsubc_c", obsrvr );
   CHKFSTR ( CHK_STANDARD, "gfsubc_c", crdsys );
   CHKFSTR ( CHK_STANDARD, "gfsubc_c", coord  );
   CHKFSTR ( CHK_STANDARD, "gfsubc_c", relate );

   /*
   Check the workspace size; some mallocs have a violent
   dislike for negative allocation amounts. To be safe,
   rule out a count of zero intervals as well.
   */

   if ( nintvls < 1 )
      {
      setmsg_c ( "The specified workspace interval count # was "
                 "less than the minimum allowed value of one (1)." );
      errint_c ( "#",  nintvls                              );
      sigerr_c ( "SPICE(VALUEOUTOFRANGE)"                   );
      chkout_c ( "gfposc_c"                                 );
      return;
      } 

   /*
   Allocate the workspace. 'nintvls' indicates the maximum number of
   intervals returned in 'result'. An interval consists of
   two values.
   */

   nintvls = 2 * nintvls;
   
   nBytes = ( nintvls + SPICE_CELL_CTRLSZ ) * nw * sizeof(SpiceDouble);

   work   = (doublereal *) alloc_SpiceMemory( nBytes );

   if ( !work ) 
      {
      setmsg_c ( "Workspace allocation of # bytes failed due to "
                 "malloc failure"                               );
      errint_c ( "#",  nBytes                                   );
      sigerr_c ( "SPICE(MALLOCFAILED)"                          );
      chkout_c ( "gfsubc_c"                                     );
      return;
      }


   /*
   Let the f2'd routine do the work.
   */

   gfsubc_ ( ( char          * ) target, 
             ( char          * ) fixref, 
             ( char          * ) method, 
             ( char          * ) abcorr, 
             ( char          * ) obsrvr, 
             ( char          * ) crdsys, 
             ( char          * ) coord, 
             ( char          * ) relate, 
             ( doublereal    * ) &refval, 
             ( doublereal    * ) &adjust, 
             ( doublereal    * ) &step, 
             ( doublereal    * ) (cnfine->base),
             ( integer       * ) &nintvls, 
             ( integer       * ) &nw, 
             ( doublereal    * ) work, 
             ( doublereal    * ) (result->base),
             ( ftnlen          ) strlen(target), 
             ( ftnlen          ) strlen(fixref), 
             ( ftnlen          ) strlen(method), 
             ( ftnlen          ) strlen(abcorr), 
             ( ftnlen          ) strlen(obsrvr), 
             ( ftnlen          ) strlen(crdsys), 
             ( ftnlen          ) strlen(coord), 
             ( ftnlen          ) strlen(relate) );

   /*
   De-allocate the workspace. 
   */
   free_SpiceMemory( work );

   /*
   Sync the output cell. 
   */
   if ( !failed_c() )
      {
      zzsynccl_c ( F2C, result ) ;
      }

   ALLOC_CHECK;

   chkout_c ( "gfsubc_c" );

   } /* End gfsubc_c */
Ejemplo n.º 20
0
   void gfposc_c ( ConstSpiceChar     * target,
                   ConstSpiceChar     * frame,
                   ConstSpiceChar     * abcorr,
                   ConstSpiceChar     * obsrvr,
                   ConstSpiceChar     * crdsys,
                   ConstSpiceChar     * coord,
                   ConstSpiceChar     * relate,
                   SpiceDouble          refval,
                   SpiceDouble          adjust,
                   SpiceDouble          step,
                   SpiceInt             nintvls,
                   SpiceCell          * cnfine,
                   SpiceCell          * result  )

/*

-Brief_I/O
 
   Variable  I/O  Description 
   --------  ---  -------------------------------------------------- 
   SPICE_GF_CNVTOL     
              P   Convergence tolerance. 
   target     I   Name of the target body
   frame      I   Name of the reference frame for coordinate calculations
   abcorr     I   Aberration correction flag
   obsrvr     I   Name of the observing body
   crdsys     I   Name of the coordinate system containing COORD
   coord      I   Name of the coordinate of interest
   relate     I   Operator that either looks for an extreme value
                  (max, min, local, absolute) or compares the
                  coordinate value and refval
   refval     I   Reference value
   adjust     I   Adjustment value for absolute extrema searches
   step       I   Step size used for locating extrema and roots
   nintvls    I   Workspace window interval count
   cnfine    I-O  SPICE window to which the search is restricted
   result     O   SPICE window containing results

-Detailed_Input

   target     the string name of a target body.  Optionally, you may
              supply the integer ID code for the object as an
              integer string.  For example both 'MOON' and '301'
              are legitimate strings that indicate the moon is the
              target body.

              The target and observer define a position vector
              that points from the observer to the target.

   frame      the string name of the reference frame in which to perform
              state look-ups and coordinate calculations.

              The SPICE frame subsystem must recognize the 'frame' name.

   abcorr     the string description of the aberration corrections to apply
              to the state evaluations to account for one-way light time
              and stellar aberration.

              This routine accepts the same aberration corrections as does 
              the SPICE routine SPKEZR. See the header of SPKEZR for a
              detailed description of the aberration correction options.
              For convenience, the options are listed below:

                  'NONE'     Apply no correction.   

                  'LT'       "Reception" case:  correct for
                             one-way light time using a Newtonian
                             formulation.

                  'LT+S'     "Reception" case:  correct for
                             one-way light time and stellar
                             aberration using a Newtonian
                             formulation.

                  'CN'       "Reception" case:  converged
                             Newtonian light time correction.

                  'CN+S'     "Reception" case:  converged
                             Newtonian light time and stellar
                             aberration corrections.

                  'XLT'      "Transmission" case:  correct for
                             one-way light time using a Newtonian
                             formulation.

                  'XLT+S'    "Transmission" case:  correct for
                             one-way light time and stellar
                             aberration using a Newtonian
                             formulation.

                  'XCN'      "Transmission" case:  converged
                             Newtonian light time correction.

                  'XCN+S'    "Transmission" case:  converged
                             Newtonian light time and stellar
                             aberration corrections.

              The abcorr string lacks sensitivity to case, and to embedded, 
              leading and trailing blanks.

   obsrvr     the string naming the observing body. Optionally, you
              may supply the ID code of the object as an integer
              string. For example, both 'EARTH' and '399' are
              legitimate strings to supply to indicate the
              observer is Earth.
              
   crdsys     the string name of the coordinate system for which the
              coordinate of interest is a member.

   coord      the string name of the coordinate of interest in crdsys.
                            
              The supported coordinate systems and coordinate names are:

              Coordinate System (CRDSYS)    Coordinates (COORD)      Range

                 'RECTANGULAR'                  'X'
                                                'Y'
                                                'Z'

                 'LATITUDINAL'                  'RADIUS'
                                                'LONGITUDE'        (-Pi,Pi]
                                                'LATITUDE'         [-Pi/2,Pi/2]

                 'RA/DEC'                       'RANGE'
                                                'RIGHT ASCENSION'  [0,2Pi)
                                                'DECLINATION'      [-Pi/2,Pi/2]

                 'SPHERICAL'                    'RADIUS'
                                                'COLATITUDE'       [0,Pi]
                                                'LONGITUDE'        (-Pi,Pi]

                 'CYLINDRICAL'                  'RADIUS'
                                                'LONGITUDE'        [0,2Pi)
                                                'Z'

                 'GEODETIC'                     'LONGITUDE'        (-Pi,Pi]
                                                'LATITUDE'         [-Pi/2,Pi/2]
                                                'ALTITUDE' 

                 'PLANETOGRAPHIC'               'LONGITUDE'        [0,2Pi)
                                                'LATITUDE'         [-Pi/2,Pi/2]
                                                'ALTITUDE'

                  Limit searches for coordinate events in the GEODETIC and 
                  PLANETOGRAPHIC coordinate systems to TARGET bodies with
                  axial symmetry in the equatorial plane, i.e. equality
                  of the body X and Y radii (oblate or prolate spheroids).

     relate    the string or character describing the relational operator 
               used to define a constraint on the selected coordinate of the 
               observer-target vector. The result window found by this routine 
               indicates the time intervals where the constraint is satisfied.
               Supported values of relate and corresponding meanings are
               shown below:

                  '>'      Separation is greater than the reference
                           value refval.

                  '='      Separation is equal to the reference
                           value refval.

                  '<'      Separation is less than the reference
                           value refval.

                 'ABSMAX'  Separation is at an absolute maximum.

                 'ABSMIN'  Separation is at an absolute  minimum.

                 'LOCMAX'  Separation is at a local maximum.

                 'LOCMIN'  Separation is at a local minimum.

              The caller may indicate that the region of interest
              is the set of time intervals where the quantity is
              within a specified measure of an absolute extremum.
              The argument ADJUST (described below) is used to
              specify this measure.

              Local extrema are considered to exist only in the
              interiors of the intervals comprising the confinement
              window:  a local extremum cannot exist at a boundary
              point of the confinement window.

              The relate string lacks sensitivity to case, leading 
              and trailing blanks.

   refval     the double precision reference value used together with
              relate argument to define an equality or inequality to
              satisfy by the selected coordinate of the observer-target
              vector. See the discussion of relate above for
              further information.

              The units of refval correspond to the type as defined
              by coord, radians for angular measures, kilometers for
              distance measures.

   adjust     a double precision value used to modify searches for
              absolute extrema: when relate is set to ABSMAX or ABSMIN and
              adjust is set to a positive value, gfposc_c finds times when the
              observer-target vector coordinate is within adjust 
              radians/kilometers of the specified extreme value.

              For relate set to ABSMAX, the result window contains
              time intervals when the observer-target vector coordinate has
              values between ABSMAX - adjust and ABSMAX.

              For relate set to ABSMIN, the result window contains
              time intervals when the observer-target vector coordinate has
              values between ABSMIN and ABSMIN + adjust.
               
              adjust is not used for searches for local extrema,
              equality or inequality conditions.

   step       the double precision time step size to use in the search.
              step must be short enough for a search using this step
              size to locate the time intervals where coordinate function
              of the observer-target vector is monotone increasing or
              decreasing. However, step must not be *too* short, or
              the search will take an unreasonable amount of time.

              The choice of step affects the completeness but not
              the precision of solutions found by this routine; the
              precision is controlled by the convergence tolerance.

              step has units of seconds. 

   nintvls    an integer value specifying the number of intervals in the 
              the internal workspace array used by this routine. 'nintvls'
              should be at least as large as the number of intervals
              within the search region on which the specified observer-target
              vector coordinate function is monotone increasing or decreasing. 
              It does no harm to pick a value of 'nintvls' larger than the
              minimum required to execute the specified search, but if chosen 
              too small, the search will fail.

   cnfine     a double precision SPICE window that confines the time
              period over which the specified search is conducted.
              cnfine may consist of a single interval or a collection
              of intervals. 

              In some cases the confinement window can be used to
              greatly reduce the time period that must be searched
              for the desired solution. See the Particulars section
              below for further discussion.
              
              See the Examples section below for a code example 
              that shows how to create a confinement window.

-Detailed_Output

   cnfine     is the input confinement window, updated if necessary
              so the control area of its data array indicates the
              window's size and cardinality. The window data are
              unchanged.

   result     the SPICE window of intervals, contained within the
              confinement window cnfine, on which the specified
              constraint is satisfied.
 
              If result is non-empty on input, its contents
              will be discarded before gfposc_c conducts its
              search.
              
              result must be declared and initialized with sufficient
              size to capture the full set of time intervals 
              within the search region on which the specified constraint 
              is satisfied.
              
              If the search is for local extrema, or for absolute
              extrema with adjust set to zero, then normally each
              interval of result will be a singleton: the left and
              right endpoints of each interval will be identical.
 
              If no times within the confinement window satisfy the
              constraint, result will be returned with a
              cardinality of zero.

-Parameters
 
   SPICE_GF_CNVTOL     

              is the convergence tolerance used for finding endpoints
              of the intervals comprising the result window.
              SPICE_GF_CNVTOL is used to determine when binary searches
              for roots should terminate: when a root is bracketed
              within an interval of length SPICE_GF_CNVTOL; the root is
              considered to have been found.
 
              The accuracy, as opposed to precision, of roots found by
              this routine depends on the accuracy of the input data.
              In most cases, the accuracy of solutions will be inferior
              to their precision.
 
              SPICE_GF_CNVTOL has the value 1.0e-6. Units are TDB
              seconds.

-Exceptions

   1)  In order for this routine to produce correct results, 
       the step size must be appropriate for the problem at hand. 
       Step sizes that are too large may cause this routine to miss 
       roots; step sizes that are too small may cause this routine 
       to run unacceptably slowly and in some cases, find spurious 
       roots. 
 
       This routine does not diagnose invalid step sizes, except 
       that if the step size is non-positive, an error is signaled 
       by a routine in the call tree of this routine. 
 
   2)  Due to numerical errors, in particular, 
 
          - Truncation error in time values 
          - Finite tolerance value 
          - Errors in computed geometric quantities 
 
       it is *normal* for the condition of interest to not always be 
       satisfied near the endpoints of the intervals comprising the 
       result window. 
 
       The result window may need to be contracted slightly by the 
       caller to achieve desired results. The SPICE window routine 
       wncond_c can be used to contract the result window. 
 
   3)  If an error (typically cell overflow) occurs while performing  
       window arithmetic, the error will be diagnosed by a routine 
       in the call tree of this routine. 
 
   4)  If the relational operator `relate' is not recognized, an  
       error is signaled by a routine in the call tree of this 
       routine. 
 
   5)   If the aberration correction specifier contains an
        unrecognized value, an error is signaled by a routine in the
        call tree of this routine.
 
   6)  If `adjust' is negative, an error is signaled by a routine in 
       the call tree of this routine. 
 
   7)  If either of the input body names do not map to NAIF ID 
       codes, an error is signaled by a routine in the call tree of 
       this routine. 
 
   8)  If required ephemerides or other kernel data are not 
       available, an error is signaled by a routine in the call tree 
       of this routine. 
 
   9)  If any input string argument pointer is null, the error
       SPICE(NULLPOINTER) will be signaled.

   10) If any input string argument is empty, the error 
       SPICE(EMPTYSTRING) will be signaled.

   11) If the workspace interval count 'nintvls' is less than 1, the
       error SPICE(VALUEOUTOFRANGE) will be signaled.

   12) If the required amount of workspace memory cannot be
       allocated, the error SPICE(MALLOCFAILURE) will be
       signaled.
       
-Files

   Appropriate SPK and PCK kernels must be loaded by the
   calling program before this routine is called.

   The following data are required:

      - SPK data: the calling application must load ephemeris data
        for the targets, observer, and any intermediate objects in 
        a chain connecting the targets and observer that cover the time
        period specified by the window CNFINE. If aberration
        corrections are used, the states of target and observer
        relative to the solar system barycenter must be calculable
        from the available ephemeris data. Typically ephemeris data
        are made available by loading one or more SPK files using
        FURNSH.

      - PCK data: bodies modeled as triaxial ellipsoids must have
        semi-axis lengths provided by variables in the kernel pool.
        Typically these data are made available by loading a text
        PCK file using FURNSH.

      - If non-inertial reference frames are used, then PCK
        files, frame kernels, C-kernels, and SCLK kernels may be
        needed.

   Such kernel data are normally loaded once per program
   run, NOT every time this routine is called. 

-Particulars

   This routine provides a simpler, but less flexible interface
   than does the routine gfevnt_c for conducting searches for
   observer-target vector coordinate value events. Applications 
   that require support for progress reporting, interrupt 
   handling, non-default step or refinement functions, or non-default 
   convergence tolerance should call gfevnt_c rather than this routine.

   This routine determines a set of one or more time intervals
   within the confinement window when the selected coordinate of 
   the observer-target vector satisfies a caller-specified
   constraint. The resulting set of intervals is returned as a SPICE
   window.

   Below we discuss in greater detail aspects of this routine's
   solution process that are relevant to correct and efficient
   use of this routine in user applications.

   The Search Process
   ==================

   Regardless of the type of constraint selected by the caller, this
   routine starts the search for solutions by determining the time
   periods, within the confinement window, over which the specified
   coordinate function is monotone increasing and monotone
   decreasing. Each of these time periods is represented by a SPICE
   window. Having found these windows, all of the coordinate
   function's local extrema within the confinement window are known.
   Absolute extrema then can be found very easily. 

   Within any interval of these "monotone" windows, there will be at
   most one solution of any equality constraint. Since the boundary
   of the solution set for any inequality constraint is the set 
   of points where an equality constraint is met, the solutions of
   both equality and inequality constraints can be found easily
   once the monotone windows have been found.


   Step Size
   =========

   The monotone windows (described above) are found using a two-step
   search process. Each interval of the confinement window is
   searched as follows: first, the input step size is used to
   determine the time separation at which the sign of the rate of
   change of coordinate will be sampled. Starting at
   the left endpoint of an interval, samples will be taken at each
   step. If a change of sign is found, a root has been bracketed; at
   that point, the time at which the time derivative of the coordinate 
   is zero can be found by a refinement process, for example,
   using a binary search.

   Note that the optimal choice of step size depends on the lengths
   of the intervals over which the coordinate function is monotone:
   the step size should be shorter than the shortest of these
   intervals (within the confinement window).

   The optimal step size is *not* necessarily related to the lengths
   of the intervals comprising the result window. For example, if
   the shortest monotone interval has length 10 days, and if the
   shortest result window interval has length 5 minutes, a step size
   of 9.9 days is still adequate to find all of the intervals in the
   result window. In situations like this, the technique of using
   monotone windows yields a dramatic efficiency improvement over a
   state-based search that simply tests at each step whether the
   specified constraint is satisfied. The latter type of search can
   miss solution intervals if the step size is shorter than the
   shortest solution interval.

   Having some knowledge of the relative geometry of the target and
   observer can be a valuable aid in picking a reasonable step size.
   In general, the user can compensate for lack of such knowledge by
   picking a very short step size; the cost is increased computation
   time.

   Note that the step size is not related to the precision with which
   the endpoints of the intervals of the result window are computed.
   That precision level is controlled by the convergence tolerance.

   Convergence Tolerance
   =====================

   As described above, the root-finding process used by this routine
   involves first bracketing roots and then using a search process
   to locate them. "Roots" are both times when local extrema are
   attained and times when the distance function is equal to a
   reference value. All endpoints of the intervals comprising the
   result window are either endpoints of intervals of the
   confinement window or roots.

   Once a root has been bracketed, a refinement process is used to
   narrow down the time interval within which the root must lie.
   This refinement process terminates when the location of the root
   has been determined to within an error margin called the
   "convergence tolerance." The convergence tolerance used by this
   routine is set by the parameter SPICE_GF_CNVTOL.

   The value of SPICE_GF_CNVTOL is set to a "tight" value in the f2c'd 
   routine so that the tolerance doesn't become the limiting factor 
   in the accuracy of solutions found by this routine. In general the 
   accuracy of input data will be the limiting factor.

   To use a different tolerance value, a lower-level GF routine such
   as gfevnt_c must be called. Making the tolerance tighter than
   SPICE_GF_CNVTOL is unlikely to be useful, since the results are unlikely
   to be more accurate. Making the tolerance looser will speed up
   searches somewhat, since a few convergence steps will be omitted.
   However, in most cases, the step size is likely to have a much
   greater effect on processing time than would the convergence
   tolerance.

   The Confinement Window
   ======================

   The simplest use of the confinement window is to specify a time
   interval within which a solution is sought. However, the
   confinement window can, in some cases, be used to make searches
   more efficient. Sometimes it's possible to do an efficient search
   to reduce the size of the time period over which a relatively
   slow search of interest must be performed.

   Practical use of the coordinate search capability would likely
   consist of searches over multiple coordinate constraints to find
   time intervals that satisfies the constraints. An effective 
   technique to accomplish such a search is to use the result
   window from one search as the confinement window of the next.

   Longitude and Right Ascension
   =============================

   The cyclic nature of the longitude and right ascension coordinates
   produces branch cuts at +/- 180 degrees longitude and 0-360
   longitude. Round-off error may cause solutions near these branches
   to cross the branch. Use of the SPICE routine wncond_c will contract
   solution windows by some epsilon, reducing the measure of the
   windows and eliminating the branch crossing. A one millisecond
   contraction will in most cases eliminate numerical round-off caused
   branch crossings.

-Examples
 
   The numerical results shown for these examples may differ across
   platforms. The results depend on the SPICE kernels used as
   input, the compiler and supporting libraries, and the machine
   specific arithmetic implementation.

   The examples shown below require a "standard" set of SPICE
   kernels. We list these kernels in a meta kernel named 'standard.tm'.
        
      KPL/MK
   
         This meta-kernel is intended to support operation of SPICE
         example programs. The kernels shown here should not be
         assumed to contain adequate or correct versions of data
         required by SPICE-based user applications.
   
         In order for an application to use this meta-kernel, the
         kernels referenced here must be present in the user's
         current working directory.
    
         The names and contents of the kernels referenced
         by this meta-kernel are as follows:
     
         File name                        Contents
         ---------                        --------
         de414.bsp                        Planetary ephemeris
         pck00008.tpc                     Planet orientation and radii
         naif0009.tls                     Leapseconds kernel
         earthstns_itrf93_050714.bsp      SPK for DSN Station Locations
         earth_topo_050714.tf             Topocentric DSN stations frame 
                                          definitions
         earth_000101_080120_071029.bpc   High precision earth PCK
   
         \begindata
   
         KERNELS_TO_LOAD = ( 
                    '/kernels/gen/lsk/naif0008.tls'
                    '/kernels/gen/spk/de414.bsp'
                    '/kernels/gen/pck/pck00008.tpc' 
                    '/kernels/gen/spk/earthstns_itrf93_050714.bsp',
                    '/kernels/gen/fk/earth_topo_050714.tf',
                    '/kernels/gen/pck/earth_000101_080120_071029.bpc',
                           )

   Example(1): 
   
      Find the time during 2007 for which the latitude of the 
      Earth-Sun vector in IAU_EARTH frame has the maximum value,
      i.e. the latitude of the Tropic of Cancer.

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>

      #include "SpiceUsr.h"

      #define       MAXWIN   750
      #define       TIMFMT   "YYYY-MON-DD HR:MN:SC.###### (TDB) ::TDB ::RND"
      #define       TIMLEN   41

      int main( int argc, char **argv )
         {

         /.
         Create the needed windows. Note, one window
         consists of two values, so the total number
         of cell values to allocate is twice
         the number of intervals.
         ./
         SPICEDOUBLE_CELL ( result, 2*MAXWIN );
         SPICEDOUBLE_CELL ( cnfine, 2       );

         SpiceDouble       begtim;
         SpiceDouble       endtim;
         SpiceDouble       step;
         SpiceDouble       adjust;
         SpiceDouble       refval;
         SpiceDouble       beg;
         SpiceDouble       end;

         SpiceChar         begstr [ TIMLEN ];
         SpiceChar         endstr [ TIMLEN ];
         SpiceChar       * relate = "ABSMAX";
         SpiceChar       * crdsys = "LATITUDINAL";
         SpiceChar       * coord  = "LATITUDE";
         SpiceChar       * targ   = "SUN";
         SpiceChar       * obsrvr = "EARTH";
         SpiceChar       * frame  = "IAU_EARTH";
         SpiceChar       * abcorr = "NONE";
   
         SpiceInt          count;
         SpiceInt          i;
   
         /.  
         Load kernels.
         ./
         furnsh_c( "standard.tm" );
   
         /.
         Store the time bounds of our search interval in
         the cnfine confinement window.
         ./
         str2et_c( "2007 JAN 01", &begtim );
         str2et_c( "2008 JAN 01", &endtim );
   
         wninsd_c ( begtim, endtim, &cnfine );

         /.  
         The latitude varies relatively slowly, ~46 degrees during the 
         year. The extrema occur approximately every six months.
         Search using a step size less than half that value (180 days).
         For this example use ninety days (in units of seconds).
         ./
         step   = (90.)*spd_c();
         adjust = 0.;
         refval = 0;

         /.  
         List the beginning and ending points in each interval
         if result contains data.
         ./
         gfposc_c (  targ,
                     frame,
                     abcorr,
                     obsrvr,
                     crdsys,
                     coord,
                     relate,
                     refval,
                     adjust,
                     step,
                     MAXWIN,
                     &cnfine,
                     &result  );

         count = wncard_c( &result );

         /.
         Display the results.
         ./
         if (count == 0 ) 
            {
            printf ( "Result window is empty.\n\n" );
            }
         else
            {
            for ( i = 0;  i < count;  i++ )
               {

               /.
               Fetch the endpoints of the Ith interval
               of the result window.
               ./
               wnfetd_c ( &result, i, &beg, &end );

               if ( beg == end )
                  {
                  timout_c ( beg, TIMFMT, TIMLEN, begstr );
                  printf ( "Event time: %s\n", begstr );
                  }
               else
                  {

                  timout_c ( beg, TIMFMT, TIMLEN, begstr ); 
                  timout_c ( end, TIMFMT, TIMLEN, endstr );

                  printf ( "Interval %d\n", i + 1);
                  printf ( "From : %s \n", begstr );
                  printf ( "To   : %s \n", endstr );
                  printf( " \n" );
                  }

               }
            }
            
         kclear_c();
         return( 0 );
         }
      
      The program outputs:

         Event time: 2007-JUN-21 17:54:13.166910 (TDB)

   Example(2): 

      A minor modification of the program listed in Example 1; find the 
      time during 2007 for which the latitude of the Earth-Sun vector
      in IAU_EARTH frame has the minimum value, i.e. the latitude of
      the Tropic of Capricorn.
   
      Edit the example program, assign:
      
         SpiceChar       * relate = "ABSMIN";
      
      The program outputs:

         Event time: 2007-DEC-22 06:04:32.630160 (TDB)

   Example(3): 

      Find the time during 2007 for which the Z component of the
      Earth-Sun vector in IAU_EARTH frame has value 0, i.e. crosses
      the equatorial plane (this also defines a zero latitude).
      The search should return two times, one for an ascending
      passage and one for descending.

      Edit the example program, assign:
   
         SpiceChar       * relate = "=";
         SpiceChar       * crdsys = "RECTANGULAR";
         SpiceChar       * coord  = "Z";

         Note, this RELATE operator refers to the REFVAL value,
         assigned to 0.D0 for this example.
      
      The program outputs:

         Event time: 2007-MAR-21 00:01:25.495120 (TDB)
         Event time: 2007-SEP-23 09:46:39.574124 (TDB)

   Example(4):

      Find the times between Jan 1, 2007 and Jan 1, 2008 corresponding
      to the apoapsis on the Moon's orbit around the Earth (note, the
      GFDIST routine can also perform this search).

      Edit the example program, assign:

         This search requires a change in the step size since the Moon's 
         orbit about the earth (earth-moon barycenter) has a twenty-eight
         day period. Use a step size something less than half that value.
         In this case, we use twelve days.

            SpiceChar       * relate = "LOCMAX";
            SpiceChar       * crdsys = "SPHERICAL";
            SpiceChar       * coord  = "RADIUS";
            SpiceChar       * targ   = "MOON";
            SpiceChar       * frame  = "J2000";

            step   = 12.*spd_c();

      The program outputs:

         Event time: 2007-JAN-10 16:26:18.805837 (TDB)
         Event time: 2007-FEB-07 12:39:35.078525 (TDB)
         Event time: 2007-MAR-07 03:38:07.334769 (TDB)
         Event time: 2007-APR-03 08:38:55.222606 (TDB)
         Event time: 2007-APR-30 10:56:49.847027 (TDB)
         Event time: 2007-MAY-27 22:03:28.857783 (TDB)
         Event time: 2007-JUN-24 14:26:23.639351 (TDB)
         Event time: 2007-JUL-22 08:43:50.135565 (TDB)
         Event time: 2007-AUG-19 03:28:33.538169 (TDB)
         Event time: 2007-SEP-15 21:07:13.964698 (TDB)
         Event time: 2007-OCT-13 09:52:30.819372 (TDB)
         Event time: 2007-NOV-09 12:32:50.070555 (TDB)
         Event time: 2007-DEC-06 16:54:31.225504 (TDB)

   Example(5):
   
      Find times between Jan 1, 2007 and Jan 1, 2008 when the latitude
      (elevation) of the observer-target vector between DSS 17 and the
      Moon, as observed in the DSS 17 topocentric (station) frame, 
      exceeds 83 degrees.

      Edit the example program, assign:

         This search uses a step size of four hours since the time 
         for all declination zero-to-max-to-zero passes within 
         the search window exceeds eight hours.

         SpiceChar       * relate = ">";
         SpiceChar       * crdsys = "LATITUDINAL";
         SpiceChar       * coord  = "LATITUDE";
         SpiceChar       * targ   = "MOON";
         SpiceChar       * obsrvr = "DSS-17";
         SpiceChar       * frame  = "DSS-17_TOPO";

         step   = (4./24.)*spd_c();
         refval = 83. * rpd_c();

      The program outputs:

         Interval 1
         From : 2007-FEB-26 03:18:48.229806 (TDB) 
         To   : 2007-FEB-26 03:31:29.734169 (TDB) 

         Interval 2
         From : 2007-MAR-25 01:12:38.551183 (TDB) 
         To   : 2007-MAR-25 01:23:53.908601 (TDB) 

-Restrictions
 
   1) The kernel files to be used by this routine must be loaded 
      (normally via the CSPICE routine furnsh_c) before this routine 
      is called. 
 
   2) This routine has the side effect of re-initializing the
      coordinate quantity utility package.  Callers may 
      need to re-initialize the package after calling this routine.
 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman   (JPL) 
   E.D. Wright    (JPL) 
 
-Version

   -CSPICE Version 1.0.1, 26-AUG-2009 (EDW)

      Correction of several typos.

   -CSPICE Version 1.0.0, 10-FEB-2009 (NJB) (EDW)

-Index_Entries

   GF position coordinate search

-&
*/

   { /* Begin gfposc_c */

   /*
   Local variables 
   */   
   doublereal            * work;

   SpiceInt                nBytes;
   
   static SpiceInt         nw = SPICE_GF_NWMAX;
   
   /*
   Participate in error tracing.
   */
   if ( return_c() )
      {
      return;
      }
   chkin_c ( "gfposc_c" );


   /*
   Make sure cell data types are d.p. 
   */
   CELLTYPECHK2 ( CHK_STANDARD, "gfposc_c", SPICE_DP, cnfine, result );
   
   /* 
   Initialize the input cells if necessary. 
   */
   CELLINIT2 ( cnfine, result );

   /*
   Check the input strings to make sure each pointer is non-null 
   and each string length is non-zero.
   */
   CHKFSTR ( CHK_STANDARD, "gfposc_c", target );
   CHKFSTR ( CHK_STANDARD, "gfposc_c", frame  );
   CHKFSTR ( CHK_STANDARD, "gfposc_c", abcorr );
   CHKFSTR ( CHK_STANDARD, "gfposc_c", obsrvr );
   CHKFSTR ( CHK_STANDARD, "gfposc_c", crdsys );
   CHKFSTR ( CHK_STANDARD, "gfposc_c", coord  );
   CHKFSTR ( CHK_STANDARD, "gfposc_c", relate );

   /*
   Check the workspace size; some mallocs have a violent
   dislike for negative allocation amounts. To be safe,
   rule out a count of zero intervals as well.
   */

   if ( nintvls < 1 )
      {
      setmsg_c ( "The specified workspace interval count # was "
                 "less than the minimum allowed value of one (1)." );
      errint_c ( "#",  nintvls                              );
      sigerr_c ( "SPICE(VALUEOUTOFRANGE)"                   );
      chkout_c ( "gfposc_c"                                 );
      return;
      } 

   /*
   Allocate the workspace. 'nintvls' indicates the maximum number of
   intervals returned in 'result'. An interval consists of
   two values.
   */

   nintvls = 2 * nintvls;
   
   nBytes = ( nintvls + SPICE_CELL_CTRLSZ ) * nw * sizeof(SpiceDouble);

   work   = (doublereal *) alloc_SpiceMemory( nBytes );

   if ( !work ) 
      {
      setmsg_c ( "Workspace allocation of # bytes failed due to "
                 "malloc failure"                               );
      errint_c ( "#",  nBytes                                   );
      sigerr_c ( "SPICE(MALLOCFAILED)"                          );
      chkout_c ( "gfposc_c"                                     );
      return;
      }


   /*
   Let the f2'd routine do the work.
   */

   gfposc_( ( char          * ) target, 
            ( char          * ) frame, 
            ( char          * ) abcorr, 
            ( char          * ) obsrvr, 
            ( char          * ) crdsys, 
            ( char          * ) coord,
            ( char          * ) relate, 
            ( doublereal    * ) &refval, 
            ( doublereal    * ) &adjust, 
            ( doublereal    * ) &step, 
            ( doublereal    * ) (cnfine->base),
            ( integer       * ) &nintvls, 
            ( integer       * ) &nw, 
            ( doublereal    * ) work,
            ( doublereal    * ) (result->base),
            ( ftnlen          ) strlen(target),
            ( ftnlen          ) strlen(frame), 
            ( ftnlen          ) strlen(abcorr), 
            ( ftnlen          ) strlen(obsrvr), 
            ( ftnlen          ) strlen(crdsys), 
            ( ftnlen          ) strlen(coord), 
            ( ftnlen          ) strlen(relate) );

   /*
   De-allocate the workspace. 
   */
   free_SpiceMemory( work );

   /*
   Sync the output cell. 
   */
   if ( !failed_c() )
      {
      zzsynccl_c ( F2C, result ) ;
      }

   ALLOC_CHECK;

   chkout_c ( "gfposc_c" );

   } /* End gfposc_c */
Ejemplo n.º 21
0
   void ekbseg_c ( SpiceInt           handle,
                   ConstSpiceChar   * tabnam,
                   SpiceInt           ncols,
                   SpiceInt           cnmlen,
                   const void       * cnames,
                   SpiceInt           declen,
                   const void       * decls,
                   SpiceInt         * segno  ) 
/*

-Brief_I/O
 
   Variable  I/O  Description 
   --------  ---  -------------------------------------------------- 
   handle     I   File handle. 
   tabnam     I   Table name. 
   ncols      I   Number of columns in the segment. 
   cnmlen     I   Length of names in in column name array.
   cnames     I   Names of columns. 
   declen     I   Length of declaration strings in declaration array.
   decls      I   Declarations of columns. 
   segno      O   Segment number. 
  
-Detailed_Input
 
   handle         the handle of an EK file that is open for writing. 
 
   tabnam         is the name of the EK table to which the current 
                  segment belongs.  All segments in the EK file 
                  designated by handle must have identical column 
                  attributes. tabnam must not exceed SPICE_EK_TNAMSZ
                  characters (see SpiceEK.h) in length.  Case is not 
                  significant. Table names must start with a letter and
                  contain only characters from the set
                  {A-Z,a-z,0-9,$,_}. 
 
   ncols          is the number of columns in a new segment. 

   cnmlen,
   cnames         are, respectively, the length of the column name
                  strings in the column name array, and the base
                  address of the array itself.  The array should have
                  dimensions
                  
                     [ncols][cnmlen]
                     
   declen,
   decls          are, respectively, the length of the declaration
                  strings in the declaration array, and the base 
                  address of the array itself.  The array should have
                  dimensions
                  
                     [ncols][declen]
                      
                  The Ith element of cnames and the Ith element of decls
                  apply to the Ith column in the segment. 
 
                  Column names must not exceed CSPICE_EK_CNAMSZ
                  characters (see SpiceEK.h) in length.  Case is not
                  significant.  Column names must start with a letter 
                  and contain only characters from the set 
                  {A-Z,a-z,0-9,$,_}. 
 
                  The declarations are strings that contain 
                  "keyword=value" assignments that define the 
                  attributes of the columns to which they apply.  The 
                  column attributes that are defined by a column 
                  declaration are: 
 
                     DATATYPE 
                     SIZE 
                     <is the column indexed?> 
                     <does the column allow null values?> 
 
                  The form of a declaration is 
 
                     "DATATYPE  = <type>, 
                      SIZE      = <size>, 
                      INDEXED   = <boolean>, 
                      NULLS_OK  = <boolean>" 
 
                  For example, an indexed, scalar, integer column 
                  that allows null values would have the declaration 
 
                     "DATATYPE  = INTEGER, 
                      SIZE      = 1, 
                      INDEXED   = TRUE, 
                      NULLS_OK  = TRUE" 
 
                  Commas are required to separate the assignments 
                  within declarations; white space is optional; 
                  case is not significant. 
 
                  The order in which the attribute keywords are 
                  listed in declaration is not significant. 
 
                  Every column in a segment must be declared. 
 
                  Each column entry is effectively an array, each 
                  element of which has the declared data type.  The 
                  SIZE keyword indicates how many elements are in 
                  each entry of the column in whose declaration the 
                  keyword appears.  Note that only scalar-valued 
                  columns (those for which SIZE = 1) may be 
                  referenced in query constraints.  A size 
                  assignment has the syntax 
 
                     SIZE = <integer> 
 
                  or 
                     SIZE = VARIABLE 
 
                  The size value defaults to 1 if omitted. 
 
                  The DATATYPE keyword defines the data type of 
                  column entries.  The DATATYPE assignment syntax 
                  has any of the forms 
 
                     DATATYPE = CHARACTER*(<length>) 
                     DATATYPE = CHARACTER*(*) 
                     DATATYPE = DOUBLE PRECISION 
                     DATATYPE = INTEGER 
                     DATATYPE = TIME 
 
                  As the datatype declaration syntax suggests, 
                  character strings may have fixed or variable 
                  length.  Variable-length strings are allowed only 
                  in columns of size 1. 
 
                  Optionally, scalar-valued columns may be indexed. 
                  To create an index for a column, use the assignment 
 
                     INDEXED = TRUE 
 
                  By default, columns are not indexed. 
 
                  Optionally, any column can allow null values.  To 
                  indicate that a column may allow null values, use 
                  the assigment 
 
                     NULLS_OK = TRUE 
 
                  in the column declaration.  By default, null 
                  values are not allowed in column entries. 

  


-Detailed_Output
 
   segno          is the number of the segment to which data is to be
                  added. Segments are numbered from 0 to nseg-1, where
                  nseg is the count of segments in the file.  Segment
                  numbers are used as unique identifiers by other EK
                  access routines.
  
-Parameters
 
   None. 
 
-Exceptions
 
   1)  If handle is invalid, the error will be diagnosed by routines 
       called by this routine. 
 
   2)  If tabnam is more than SPICE_EK_TNAMSZ characters long, the 
       error is diagnosed by routines called by this routine. 
 
   3)  If tabnam contains any nonprintable characters, the error 
       is diagnosed by routines called by this routine. 
 
   4)  If ncols is non-positive or greater than the maximum allowed 
       number SPICE_EK_MXCLSG, the error SPICE(INVALIDCOUNT) is 
       signaled. 
 
   5)  If any column name exceeds SPICE_EK_CNAMSZ characters in 
       length, the error is diagnosed by routines called by this 
       routine. 
 
   6)  If any column name contains non-printable characters, the 
       error is diagnosed by routines called by this routine. 
 
   7)  If a declaration cannot be understood by this routine, the 
       error is diagnosed by routines called by this routine. 
 
   8)  If an non-positive string length or element size is specified, 
       the error is diagnosed by routines called by this routine. 
 
   9)  If an I/O error occurs while reading or writing the indicated 
       file, the error will be diagnosed by routines called by this 
       routine. 

   10) If the input string pointer for the table name is null, the 
       error SPICE(NULLPOINTER) will be signaled.
      
   12) If the input tablen name string has length zero, the error 
       SPICE(EMPTYSTRING) will be signaled.
 
   13) If the string pointer for cnames is null, the error
       SPICE(NULLPOINTER) will be signaled.
   
   14) If the string length cnmlen is less than 2, the error 
       SPICE(STRINGTOOSHORT) will be signaled.

   15) If the string pointer for decls is null, the error
       SPICE(NULLPOINTER) will be signaled.
   
   16) If the string length declen is less than 2, the error 
       SPICE(STRINGTOOSHORT) will be signaled.
   
-Files
 
   See the EK Required Reading for a discussion of the EK file 
   format. 
 
-Particulars
 
   This routine operates by side effects:  it prepares an EK for 
   the addition of a new segment.  It is not necessary to take 
   any special action to `complete' a segment; segments are readable 
   after the completion of any record insertion, deletion, write, 
   or update operation. 
 
-Examples
 
   1)  Suppose we have an E-kernel named ORDER_DB.EK which contains 
       records of orders for data products.  The E-kernel has a 
       table called DATAORDERS that consists of the set of columns 
       listed below: 
 
          DATAORDERS 
 
             Column Name     Data Type 
             -----------     --------- 
             ORDER_ID        INTEGER 
             CUSTOMER_ID     INTEGER 
             LAST_NAME       CHARACTER*(*) 
             FIRST_NAME      CHARACTER*(*) 
             ORDER_DATE      TIME 
             COST            DOUBLE PRECISION 
 
       The order database also has a table of items that have been 
       ordered.  The columns of this table are shown below: 
 
          DATAITEMS 
 
             Column Name     Data Type 
             -----------     --------- 
             ITEM_ID         INTEGER 
             ORDER_ID        INTEGER 
             ITEM_NAME       CHARACTER*(*) 
             DESCRIPTION     CHARACTER*(*) 
             PRICE           DOUBLE PRECISION 
 
 
       We'll suppose that the file ORDER_DB.EK contains two segments, 
       the first containing the DATAORDERS table and the second 
       containing the DATAITEMS table. 
 
       Below, we show how we'd open a new EK file and start the 
       first of the segments described above. 
 
       
       #include "SpiceUsr.h"
       #include <stdio.h>
       
       
       void main()
       {
          /.
          Constants
          ./
          #define  CNMLEN        SPICE_EK_CSTRLN
          #define  DECLEN        201
          #define  EKNAME        "order_db.ek"
          #define  FNMLEN        50
          #define  IFNAME        "Test EK/Created 20-SEP-1995"
          #define  LNMLEN        50
          #define  LSK           "leapseconds.ker"
          #define  NCOLS         6
          #define  NRESVC        0
          #define  TABLE         "DATAORDERS"
          #define  TNMLEN        CSPICE_EK_TAB_NAM_LEN
          #define  UTCLEN        30
          
          
          /.
          Local variables
          ./
          SpiceBoolean            nlflgs [ NROWS  ];
       
          SpiceChar               cdecls  [ NCOLS ] [ DECLEN ];
          SpiceChar               cnames  [ NCOLS ] [ CNMLEN ];
          SpiceChar               fnames  [ NROWS ] [ FNMLEN ];
          SpiceChar               lnames  [ NROWS ] [ LNMLEN ];
          SpiceChar               dateStr [ UTCLEN ];
        
          SpiceDouble             costs  [ NROWS ];
          SpiceDouble             ets    [ NROWS ];
       
          SpiceInt                cstids [ NROWS ];
          SpiceInt                ordids [ NROWS ];
          SpiceInt                handle;
          SpiceInt                i;
          SpiceInt                segno;
          SpiceInt                sizes  [ NROWS ];
          
          
          /.
          Load a leapseconds kernel for UTC/ET conversion.
          ./
          furnsh_c ( LSK );
          
          /.
          Open a new EK file.  For simplicity, we will not 
          reserve any space for the comment area, so the 
          number of reserved comment characters is zero. 
          The constant IFNAME is the internal file name. 
          ./
          ekopn_c ( EKNAME, IFNAME, NRESVC, &handle );
       
          /.
          Set up the table and column names and declarations 
          for the DATAORDERS segment.  We'll index all of 
          the columns.  All columns are scalar, so we omit 
          the size declaration.  Only the COST column may take 
          null values. 
          ./
          strcpy ( cnames[0], "ORDER_ID"                           );
          strcpy ( cdecls[0], "DATATYPE = INTEGER, INDEXED = TRUE" );
       
          strcpy ( cnames[1], "CUSTOMER_ID"                        );
          strcpy ( cdecls[1], "DATATYPE = INTEGER, INDEXED = TRUE" );
       
          strcpy ( cnames[2], "LAST_NAME"                          ); 
          strcpy ( cdecls[2], "DATATYPE = CHARACTER*(*),"
                              "INDEXED  = TRUE"                    );
       
          strcpy ( cnames[3], "FIRST_NAME"                         );
          strcpy ( cdecls[3], "DATATYPE = CHARACTER*(*),"   
                              "INDEXED  = TRUE"                    );
       
          strcpy ( cnames[4], "ORDER_DATE"                         );
          strcpy ( cdecls[4], "DATATYPE = TIME, INDEXED  = TRUE"   );
       
          strcpy ( cnames[5], "COST"                               );
          strcpy ( cdecls[5], "DATATYPE = DOUBLE PRECISION,"   
                              "INDEXED  = TRUE,"             
                              "NULLS_OK = TRUE"                    );
          /.
          Start the segment. 
          ./
          ekbseg_c ( handle,  TABLE,   NCOLS,   CNMLEN,  
                     cnames,  DECLEN,  cdecls,  &segno  );

          /. 
          Add data to the segment.  No special action 
          is required to finish the segment. 
          ./
             [Data are added via calls to ekappr_c and the 
              ekacec_c, ekaced_c, and ekacei_c routines.  See any 
              of these routines for examples.] 
 
          /.
          At this point, the second segment could be 
          created by an analogous process.  In fact, the 
          second segment could be created at any time; it is 
          not necessary to populate the first segment with 
          data before starting the second segment. 
          ./ 

 
          /. 
          The file must be closed by a call to ekcls_c. 
          ./
          ekcls_c ( handle ); 
       }
  
 
-Restrictions
 
   None. 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman   (JPL) 
 
-Version
 
   -CSPICE Version 1.1.0, 12-JUL-2002 (NJB)

      Call to C2F_CreateStrArr_Sig replaced with call to C2F_MapStrArr.

   -CSPICE Version 1.0.0, 17-NOV-2001 (NJB)

-Index_Entries
 
   start new E-kernel segment 
   start new EK segment 
 
-&
*/

{ /* Begin ekbseg_c */



   /*
   Local variables
   */
   SpiceChar             * fCnameArr;
   SpiceChar             * fCdeclArr;

   SpiceInt                fCnameLen;
   SpiceInt                fCdeclLen;

   /*
   Participate in error tracing.
   */
   chkin_c ( "ekbseg_c" );

   /*
   Check the table name to make sure the pointer is non-null 
   and the string length is non-zero.
   */
   CHKFSTR ( CHK_STANDARD, "ekbseg_c", tabnam );

   /*
   Check the column name array to make sure the pointer is non-null 
   and the string length is non-zero.  Note:  this check is normally
   done for output strings:  CHKOSTR is the macro that does the job.
   */
   CHKOSTR ( CHK_STANDARD, "ekbseg_c", cnames, cnmlen );

   /*
   Check the declaration array to make sure the pointer is non-null 
   and the string length is non-zero.
   */
   CHKOSTR ( CHK_STANDARD, "ekbseg_c", decls, declen );

   C2F_MapStrArr ( "ekbseg_c", 
                   ncols, cnmlen, cnames, &fCnameLen, &fCnameArr );
   
   if ( failed_c() )
   {
      chkout_c ( "ekbseg_c" );
      return;
   }


   C2F_MapStrArr ( "ekbseg_c", 
                   ncols, declen, decls, &fCdeclLen, &fCdeclArr );
   
   if ( failed_c() )
   {
      free ( fCnameArr );
      
      chkout_c ( "ekbseg_c" );
      return;
   }
   

   /*
   Call the f2c'd Fortran routine.  Use explicit type casts for every
   type defined by f2c.
   */
   ekbseg_ ( ( integer  * ) &handle,
             ( char     * ) tabnam,
             ( integer  * ) &ncols,
             ( char     * ) fCnameArr,
             ( char     * ) fCdeclArr,
             ( integer  * ) segno,
             ( ftnlen     ) strlen(tabnam),
             ( ftnlen     ) fCnameLen,
             ( ftnlen     ) fCdeclLen       );

   /*
   Clean up all of our dynamically allocated arrays.
   */
   free ( fCnameArr );
   free ( fCdeclArr );

   /*
   Map segno to C style range.
   */
   
   (*segno)--;
   
   
   chkout_c ( "ekbseg_c" );

} /* End ekbseg_c */
Ejemplo n.º 22
0
//------------------------------------------------------------------------------
void  SpiceOrbitKernelReader::GetCoverageStartAndEnd(StringArray       &kernels,
                                                     Integer           forNaifId,
                                                     Real              &start,
                                                     Real              &end)
{
   // first check to see if a kernel specified is not loaded; if not,
   // try to load it
   for (unsigned int ii = 0; ii < kernels.size(); ii++)
      if (!IsLoaded(kernels.at(ii)))   LoadKernel(kernels.at(ii));

   SpiceInt         idSpice     = forNaifId;
   SpiceInt         arclen      = 4;
   SpiceInt         typlen      = 5;
   bool             firstInt    = true;
   bool             idOnKernel  = false;
   ConstSpiceChar   *kernelName = NULL;
   SpiceInt         objId       = 0;
   SpiceInt         numInt      = 0;
   SpiceChar        *kernelType;
   SpiceChar        *arch;
   SpiceDouble      b;
   SpiceDouble      e;
   Real             bA1;
   Real             eA1;
   SPICEINT_CELL(ids, 200);
   SPICEDOUBLE_CELL(cover, 200000);
   char             kStr[5] = "    ";
   char             aStr[4] = "   ";

   // look through each kernel
   for (unsigned int ii = 0; ii < kernels.size(); ii++)
   {
      #ifdef DEBUG_SPK_COVERAGE
         MessageInterface::ShowMessage(wxT("Checking coverage for ID %d on kernel %s\n"),
               forNaifId, (kernels.at(ii)).c_str());
      #endif
      kernelName = kernels[ii].char_str();
      // check the type of kernel
      arch        = aStr;
      kernelType  = kStr;
      getfat_c(kernelName, arclen, typlen, arch, kernelType);
      if (failed_c())
      {
         ConstSpiceChar option[] = "LONG";
         SpiceInt       numChar  = MAX_LONG_MESSAGE_VALUE;
         //SpiceChar      err[MAX_LONG_MESSAGE_VALUE];
         SpiceChar      *err = new SpiceChar[MAX_LONG_MESSAGE_VALUE];
         getmsg_c(option, numChar, err);
         wxString errStr(wxString::FromAscii(err));
         wxString errmsg = wxT("Error determining type of kernel \"");
         errmsg += kernels.at(ii) + wxT("\".  Message received from CSPICE is: ");
         errmsg += errStr + wxT("\n");
         reset_c();
         delete [] err;
         throw UtilityException(errmsg);
      }
      #ifdef DEBUG_SPK_COVERAGE
         MessageInterface::ShowMessage(wxT("Kernel is of type %s\n"),
               kernelType);
      #endif
      // only deal with SPK kernels
      if (eqstr_c( kernelType, "spk" ))
      {
         spkobj_c(kernelName, &ids);
         // get the list of objects (IDs) for which data exists in the SPK kernel
         for (SpiceInt jj = 0;  jj < card_c(&ids);  jj++)
         {
            objId = SPICE_CELL_ELEM_I(&ids,jj);
            #ifdef DEBUG_SPK_COVERAGE
               MessageInterface::ShowMessage(wxT("Kernel contains data for object %d\n"),
                     (Integer) objId);
            #endif
            // look to see if this kernel contains data for the object we're interested in
            if (objId == idSpice)
            {
               idOnKernel = true;
               break;
            }
         }
         // only deal with kernels containing data for the object we're interested in
         if (idOnKernel)
         {
            #ifdef DEBUG_SPK_COVERAGE
               MessageInterface::ShowMessage(wxT("Checking kernel %s for data for object %d\n"),
                     (kernels.at(ii)).c_str(), (Integer) objId);
            #endif
            scard_c(0, &cover);   // reset the coverage cell
            spkcov_c (kernelName, idSpice, &cover);
            if (failed_c())
            {
               ConstSpiceChar option[] = "LONG";
               SpiceInt       numChar  = MAX_LONG_MESSAGE_VALUE;
               //SpiceChar      err[MAX_LONG_MESSAGE_VALUE];
               SpiceChar      *err = new SpiceChar[MAX_LONG_MESSAGE_VALUE];
               getmsg_c(option, numChar, err);
               wxString errStr(wxString::FromAscii(err));
               wxString errmsg = wxT("Error determining coverage for SPK kernel \"");
               errmsg += kernels.at(ii) + wxT("\".  Message received from CSPICE is: ");
               errmsg += errStr + wxT("\n");
               reset_c();
               delete [] err;
               throw UtilityException(errmsg);
            }
            numInt = wncard_c(&cover);
            #ifdef DEBUG_SPK_COVERAGE
               MessageInterface::ShowMessage(wxT("Number of intervals found =  %d\n"),
                     (Integer) numInt);
            #endif
            if ((firstInt) && (numInt > 0))
            {
               wnfetd_c(&cover, 0, &b, &e);
               if (failed_c())
               {
                  ConstSpiceChar option[] = "LONG";
                  SpiceInt       numChar  = MAX_LONG_MESSAGE_VALUE;
                  //SpiceChar      err[MAX_LONG_MESSAGE_VALUE];
                  SpiceChar      *err = new SpiceChar[MAX_LONG_MESSAGE_VALUE];
                  getmsg_c(option, numChar, err);
                  wxString errStr(wxString::FromAscii(err));
                  wxString errmsg = wxT("Error getting interval times for SPK kernel \"");
                  errmsg += kernels.at(ii) + wxT("\".  Message received from CSPICE is: ");
                  errmsg += errStr + wxT("\n");
                  reset_c();
                  delete [] err;
                  throw UtilityException(errmsg);
               }
               start    = SpiceTimeToA1(b);
               end      = SpiceTimeToA1(e);
               firstInt = false;
            }
            for (SpiceInt jj = 0; jj < numInt; jj++)
            {
               wnfetd_c(&cover, jj, &b, &e);
               bA1 = SpiceTimeToA1(b);
               eA1 = SpiceTimeToA1(e);
               if (bA1 < start)  start = bA1;
               if (eA1 > end)    end   = eA1;
            }
         }

      }
   }
   if (firstInt)
   {
      wxString errmsg(wxT(""));
      errmsg << wxT("Error - no data available for body with NAIF ID ") << forNaifId << wxT(" on specified SPK kernels\n");
      throw UtilityException(errmsg);
   }
}
Ejemplo n.º 23
0
   void swpool_c ( ConstSpiceChar    * agent,
                   SpiceInt            nnames,
                   SpiceInt            lenvals,
                   const void        * names   ) 
/*

-Brief_I/O
 
   VARIABLE  I/O  DESCRIPTION 
   --------  ---  -------------------------------------------------- 
   agent      I   The name of an agent to be notified after updates. 
   nnames     I   The number of variables to associate with agent. 
   lenvals    I   Length of strings in the names array.
   names      I   Variable names whose update causes the notice. 
 
-Detailed_Input
 
   agent       is the name of a routine or entry point (agency) that 
               will want to know when a some variables in the kernel 
               pool have been updated. 
 
   nnames      is the number of kernel pool variable names that will 
               be associated with agent. 
 
   lenvals     is the length of the strings in the array names, 
               including the null terminators.  
              
   names       is an array of names of variables in the kernel pool. 
               Whenever any of these is updated, a notice will be 
               posted for agent so that one can quickly check 
               whether needed data has been modified. 
 
-Detailed_Output
 
   None. 
 
-Parameters
 
   None. 
 
-Files
 
   None. 
 
-Exceptions
 
   1) If sufficient room is not available to hold a name or new agent,
      a routine in the call tree for this routine will signal an error.
 
   2) If either of the input string pointers are null, the error 
      SPICE(NULLPOINTER) will be signaled.
      
   3) If any input string agent has length zero, the error 
      SPICE(EMPTYSTRING) will be signaled.
      
   4) The caller must pass a value indicating the length of the strings
      in the names array.  If this value is not at least 2, the error
      SPICE(STRINGTOOSHORT) will be signaled.
      
-Particulars
 
   The kernel pool is a convenient place to store a wide variety of
   data needed by routines in CSPICE and routines that interface with
   CSPICE routines.  However, when a single name has a large quantity
   of data associated with it, it becomes inefficient to constantly
   query the kernel pool for values that are not updated on a frequent
   basis.
 
   This entry point allows a routine to instruct the kernel pool to
   post a message whenever a particular value gets updated. In this
   way, a routine can quickly determine whether or not data it requires
   has been updated since the last time the data was accessed.  This
   makes it reasonable to buffer the data in local storage and update
   it only when a variable in the kernel pool that affects this data
   has been updated.
 
   Note that swpool_c has a side effect.  Whenever a call to swpool_c
   is made, the agent specified in the calling sequence is added to the
   list of agents that should be notified that an update of its
   variables has occurred.  In other words the code
 
       swpool_c ( agent, nnames, lenvals, names   ); 
       cvpool_c ( agent,                  &update ); 
 
   will always return update as SPICETRUE. 
 
   This feature allows for a slightly cleaner use of swpool_c and
   cvpool_c as shown in the example below.  Because swpool_c
   automatically loads agent into the list of agents to notify of a
   kernel pool update, you do not have to include the code for fetching
   the initial values of the kernel variables in the initialization
   portion of a subroutine.  Instead, the code for the first fetch from
   the pool is the same as the code for fetching when the pool is
   updated.
 
-Examples
 
   Suppose that you have an application subroutine, MYTASK, that 
   needs to access a large data set in the kernel pool.  If this 
   data could be kept in local storage and kernel pool queries 
   performed only when the data in the kernel pool has been 
   updated, the routine can perform much more efficiently. 
 
   The code fragment below illustrates how you might make use of this 
   feature. 
 
      #include "SpiceUsr.h"
           .
           .
           .
      /.  
      On the first call to this routine establish those variables 
      that we will want to read from the kernel pool only when 
      new values have been assigned. 
      ./
      if ( first )
      {
         first = SPICEFALSE;
         swpool_c ( "MYTASK", nnames, lenvals, names ); 
      }
 
      /.
      If any of the variables has been updated, fetch them from the
      kernel pool.
      ./    
        
      cvpool_c ( "MYTASK", &update ); 
 
      if ( update )
      {
         for ( i = 0;  i < NVAR;  i++ )
         {
            gdpool_c( MYTASK_VAR[i], 1, NMAX, n[i], val[i], &found[i] );
         }
      }
 
 
-Restrictions
 
   None. 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman    (JPL)
   W.L. Taber      (JPL) 
 
-Version
 
   -CSPICE Version 1.3.0, 27-AUG-2002 (NJB)

      Call to C2F_CreateStrArr_Sig replaced with call to C2F_MapStrArr.

   -CSPICE Version 1.2.0, 28-AUG-2001 (NJB)

      Const-qualified input array names.

   -CSPICE Version 1.1.0, 14-FEB-2000 (NJB)

       Calls to C2F_CreateStrArr replaced with calls to error-signaling 
       version of this routine:  C2F_CreateStrArr_Sig.
      
   -CSPICE Version 1.0.0, 05-JUN-1999 (NJB) (WLT)

-Index_Entries
 
   Watch for an update to a kernel pool variable 
   Notify a routine of an update to a kernel pool variable 
-&
*/

{ /* Begin swpool_c */


   /*
   Local variables
   */

   SpiceChar             * fCvalsArr;

   SpiceInt                fCvalsLen;


   /*
   Participate in error tracing.
   */
   chkin_c ( "swpool_c" );


   /*
   Make sure the input string pointer for agent is non-null 
   and that the length is sufficient.  
   */
   CHKFSTR ( CHK_STANDARD, "swpool_c", agent );

   /*
   Make sure the input string pointer for the names array is non-null 
   and that the length lenvals is sufficient.  
   */
   CHKOSTR ( CHK_STANDARD, "swpool_c", names, lenvals );

   /*
   Create a Fortran-style string array.
   */
   C2F_MapStrArr ( "swpool_c", 
                   nnames, lenvals, names, &fCvalsLen,  &fCvalsArr );

   if ( failed_c() )
   {
      chkout_c ( "swpool_c" );
      return;
   }


   /*
   Call the f2c'd routine.
   */
   swpool_ (  ( char       * ) agent,
              ( integer    * ) &nnames,
              ( char       * ) fCvalsArr,
              ( ftnlen       ) strlen(agent),
              ( ftnlen       ) fCvalsLen      );


   /*
   Free the dynamically allocated array.
   */
   free ( fCvalsArr );


   chkout_c ( "swpool_c" );

} /* End swpool_c */
Ejemplo n.º 24
0
//------------------------------------------------------------------------------
Rvector6 SpiceOrbitKernelReader::GetTargetState(const wxString &targetName,
                                 const Integer     targetNAIFId,
                                 const A1Mjd       &atTime,
                                 const wxString &observingBodyName,
                                 const wxString &referenceFrame,
                                 const wxString &aberration)
{
   #ifdef DEBUG_SPK_READING
      MessageInterface::ShowMessage(
            wxT("Entering SPKReader::GetTargetState with target = %s, naifId = %d, time = %12.10f, observer = %s\n"),
            targetName.c_str(), targetNAIFId, atTime.Get(), observingBodyName.c_str());
      Real start, end;
      GetCoverageStartAndEnd(loadedKernels, targetNAIFId, start, end);
      MessageInterface::ShowMessage(wxT("   coverage for object %s : %12.10f --> %12.10f\n"),
            targetName.c_str(), start, end);
   #endif
   wxString targetNameToUse = GmatStringUtil::ToUpper(targetName);
   if (targetNameToUse == wxT("LUNA"))  // We use Luna, instead of Moon, for GMAT
      targetNameToUse        = wxT("MOON");
   if (targetNameToUse == wxT("SOLARSYSTEMBARYCENTER"))
      targetNameToUse = wxT("SSB");
   objectNameSPICE           = targetNameToUse.char_str();
   observingBodyNameSPICE    = observingBodyName.char_str();
   referenceFrameSPICE       = referenceFrame.char_str();
   aberrationSPICE           = aberration.char_str();
   // convert time to Ephemeris Time (TDB)
   etSPICE                   = A1ToSpiceTime(atTime.Get());
   naifIDSPICE               = targetNAIFId;
   boddef_c(objectNameSPICE, naifIDSPICE);        // CSPICE method to set NAIF ID for an object

   #ifdef DEBUG_SPK_READING
      MessageInterface::ShowMessage(wxT("SET NAIF Id for object %s to %d\n"),
            targetNameToUse.c_str(), targetNAIFId);
//      MessageInterface::ShowMessage(
//            wxT("In SPKReader::Converted (to TBD) time = %12.10f\n"), etMjdAtTime);
//      MessageInterface::ShowMessage(wxT("  then the full JD = %12.10f\n"),
//            (etMjdAtTime + GmatTimeConstants::JD_JAN_5_1941));
      MessageInterface::ShowMessage(wxT("So time passed to SPICE is %12.14f\n"), (Real) etSPICE);
   #endif
   SpiceDouble state[6];
   SpiceDouble oneWayLightTime;
   spkezr_c(objectNameSPICE, etSPICE, referenceFrameSPICE, aberrationSPICE,
            observingBodyNameSPICE, state, &oneWayLightTime);
#ifdef DEBUG_SPK_PLANETS
   Real        ttMjdAtTime   = TimeConverterUtil::Convert(atTime.Get(), TimeConverterUtil::A1MJD,
                               TimeConverterUtil::TTMJD, GmatTimeConstants::JD_JAN_5_1941);
//   Real etJd                 = etMjdAtTime + GmatTimeConstants::JD_JAN_5_1941;
   Real ttJd                 = ttMjdAtTime + GmatTimeConstants::JD_JAN_5_1941;
   MessageInterface::ShowMessage(wxT("Asking CSPICE for state of body %s, with observer %s, referenceFrame %s, and aberration correction %s\n"),
         objectNameSPICE, observingBodyNameSPICE, referenceFrameSPICE, aberrationSPICE);
   MessageInterface::ShowMessage(
         wxT("           Body: %s   TT Time:  %12.10f  TDB Time: %12.10f   state:  %12.10f  %12.10f  %12.10f  %12.10f  %12.10f  %12.10f\n"),
         targetName.c_str(), ttJd, /*etJd,*/ state[0], state[1], state[2], state[3], state[4], state[5]);
#endif
   if (failed_c())
   {
//      ConstSpiceChar option[] = wxT("SHORT"); // retrieve short error message, for now
//      SpiceInt       numChar  = MAX_SHORT_MESSAGE;
//      SpiceChar      err[MAX_SHORT_MESSAGE];
      ConstSpiceChar option[] = "LONG"; // retrieve long error message, for now
      SpiceInt       numChar  = MAX_LONG_MESSAGE_VALUE;
      //SpiceChar      err[MAX_LONG_MESSAGE_VALUE];
      SpiceChar      *err = new SpiceChar[MAX_LONG_MESSAGE_VALUE];
      getmsg_c(option, numChar, err);
      wxString errStr(wxString::FromAscii(err));
      wxString errmsg = wxT("Error getting state for body \"");
      errmsg += targetName + wxT("\".  Message received from CSPICE is: ");
      errmsg += errStr + wxT("\n");
      reset_c();
      delete [] err;
      throw UtilityException(errmsg);
   }
   #ifdef DEBUG_SPK_READING
      MessageInterface::ShowMessage(
            wxT("In SPKReader::Called spkezr_c and got state out\n"));
   #endif


   Rvector6 r6(state[0],state[1],state[2],state[3],state[4],state[5]);
   return r6;
}
Ejemplo n.º 25
0
   void gfuds_c (  void             ( * udfunc ) ( SpiceDouble       et,
                                                   SpiceDouble     * value ),

                   void             ( * udqdec ) ( void ( * udfunc ) 
                                                        ( SpiceDouble   et,
                                                          SpiceDouble * value ),

                                                   SpiceDouble       et,
                                                   SpiceBoolean    * isdecr ),

                   ConstSpiceChar     * relate,
                   SpiceDouble          refval,
                   SpiceDouble          adjust,
                   SpiceDouble          step,
                   SpiceInt             nintvls,
                   SpiceCell          * cnfine,
                   SpiceCell          * result )

/*

-Brief_I/O
 
   VARIABLE  I/O  DESCRIPTION
   --------  ---  --------------------------------------------------

   udfunc     I   Name of the routine that computes the scalar value
                  of interest at some time.
   udqdec     I   Name of the routine that computes whether the 
                  current state is decreasing.
   relate     I   Operator that either looks for an extreme value
                  (max, min, local, absolute) or compares the
                  geometric quantity value and a number.
   refval     I   Value used as reference for geometric quantity 
                  condition.
   adjust     I   Allowed variation for absolute extremal 
                  geometric conditions.
   step       I   Step size used for locating extrema and roots.
   nintvls    I   Workspace window interval count
   cnfine    I-O  SPICE window to which the search is restricted.
   result     O   SPICE window containing results.
 
-Detailed_Input

   udfunc     the name of the external routine that returns the 
              value of the scalar quantity of interest at time ET.
              The calling sequence for "udfunc" is:

                 udfunc ( et, &value )

              where:

                 et      an input double precision value 
                         representing the TDB ephemeris seconds time 
                         at which to determine the scalar value.

                 value   is the value of the geometric quantity 
                         at 'et'.

   udqdec     the name of the external routine that determines if
              the scalar quantity calculated by "udfunc" is decreasing.

              The calling sequence:

                 udqdec ( et, &isdecr )

              where:

                 et       an input double precision value representing
                          the TDB ephemeris seconds time at at which
                          to determine the time derivative of 'udfunc'.

                 isdecr   a logical variable indicating whether
                          or not the scalar value returned by udfunc
                          is decreasing. 'isdecr' returns true if the 
                          time derivative of "udfunc" at 'et' is negative.

   relate     the scalar string comparison operator indicating 
              the numeric constraint of interest. Values are:
     
                 ">"       value of scalar quantity greater than some
                           reference (refval).
     
                 "="       value of scalar quantity equal to some
                           reference (refval).
     
                 "<"       value of scalar quantity less than some
                           reference (refval).
     
                 "ABSMAX"  The scalar quantity is at an absolute
                           maximum.
     
                 "ABSMIN"  The scalar quantity is at an absolute
                            minimum.
     
                 "LOCMAX"  The scalar quantity is at a local 
                           maximum.
     
                 "LOCMIN"  The scalar quantity is at a local 
                           minimum.
     
              The caller may indicate that the region of interest
              is the set of time intervals where the quantity is
              within a specified distance of an absolute extremum.
              The argument 'adjust' (described below) is used to
              specified this distance.
     
              Local extrema are considered to exist only in the
              interiors of the intervals comprising the confinement
              window:  a local extremum cannot exist at a boundary
              point of the confinement window.
     
              relate is insensitive to case, leading and 
              trailing blanks.

   refval    is the reference value used to define an equality or
              inequality to  satisfied by the scalar quantity.
              The units of refval are those of the scalar quantity.

   adjust     the amount by which the quantity is allowed to vary
              from an absolute extremum.
                  
              If the search is for an absolute minimum is performed, 
              the resulting window contains time intervals when the 
              geometric quantity value has values between ABSMIN and 
              ABSMIN + adjust.
     
              If the search is for an absolute maximum, the
              corresponding range is  between ABSMAX - adjust and
              ABSMAX.
     
              'adjust' is not used for searches for local extrema,
              equality or inequality conditions and must have value
              zero for such searches.

   step       the double precision time step size to use in 
              the search.

              'step' must be short enough to for a search using this
              step size to locate the time intervals where the
              scalar quantity function is monotone increasing or
              decreasing. However, 'step' must not be *too* short,
              or the search will take an 

              The choice of 'step' affects the completeness but not
              the precision of solutions found by this routine; the
              precision is controlled by the convergence tolerance.
              See the discussion of the parameter SPICE_GF_CNVTOL for
              details.

              'step' has units of TDB seconds.

   nintvls    an integer value specifying the number of intervals in the 
              the internal workspace array used by this routine. 'nintvls'
              should be at least as large as the number of intervals
              within the search region on which the specified observer-target
              vector coordinate function is monotone increasing or decreasing. 
              It does no harm to pick a value of 'nintvls' larger than the
              minimum required to execute the specified search, but if chosen 
              too small, the search will fail.

   cnfine     a double precision SPICE window that confines the time
              period over which the specified search is conducted.
              cnfine may consist of a single interval or a collection
              of intervals. 

              In some cases the confinement window can be used to
              greatly reduce the time period that must be searched
              for the desired solution. See the Particulars section
              below for further discussion.
              
              See the Examples section below for a code example 
              that shows how to create a confinement window.

-Detailed_Output
 
   cnfine     is the input confinement window, updated if necessary
              so the control area of its data array indicates the
              window's size and cardinality. The window data are
              unchanged.

   result     is a SPICE window representing the set of time 
              intervals, within the confinement period, when the 
              specified geometric event occurs. 
 
              If `result' is non-empty on input, its contents 
              will be discarded before gfuds_c conducts its 
              search. 
 
-Parameters
 
   None.
 
-Exceptions 

   1)  In order for this routine to produce correct results, 
       the step size must be appropriate for the problem at hand. 
       Step sizes that are too large may cause this routine to miss 
       roots; step sizes that are too small may cause this routine 
       to run unacceptably slowly and in some cases, find spurious 
       roots. 
 
       This routine does not diagnose invalid step sizes, except 
       that if the step size is non-positive, an error is signaled 
       by a routine in the call tree of this routine. 
 
   2)  Due to numerical errors, in particular, 
 
          - Truncation error in time values 
          - Finite tolerance value 
          - Errors in computed geometric quantities 
 
       it is *normal* for the condition of interest to not always be 
       satisfied near the endpoints of the intervals comprising the 
       result window. 
 
       The result window may need to be contracted slightly by the 
       caller to achieve desired results. The SPICE window routine 
       wncond_c can be used to contract the result window. 
 
   3)  If an error (typically cell overflow) occurs while performing  
       window arithmetic, the error will be diagnosed by a routine 
       in the call tree of this routine. 
 
   4)  If the relational operator `relate' is not recognized, an  
       error is signaled by a routine in the call tree of this 
       routine. 
       
   5)  If 'adjust' is negative, the error SPICE(VALUEOUTOFRANGE) will
       signal from a routine in the call tree of this routine. 

       A non-zero value for 'adjust' when 'relate' has any value other than 
       "ABSMIN" or "ABSMAX" causes the error SPICE(INVALIDVALUE) to
       signal from a routine in the call tree of this routine. 
  
   6)  If required ephemerides or other kernel data are not 
       available, an error is signaled by a routine in the call tree 
       of this routine. 
 
   7)  If the workspace interval count is less than 1, the error
       SPICE(VALUEOUTOFRANGE) will be signaled.

   8)  If the required amount of workspace memory cannot be
       allocated, the error SPICE(MALLOCFAILURE) will be
       signaled.

   9)  If any input string argument pointer is null, the error
       SPICE(NULLPOINTER) will be signaled.

   10) If any input string argument is empty, the error 
       SPICE(EMPTYSTRING) will be signaled.

   11) If either input cell has type other than SpiceDouble,
       the error SPICE(TYPEMISMATCH) is signaled.

-Files

   Appropriate kernels must be loaded by the calling program before
   this routine is called.

   If the scalar function requires access to ephemeris data:

      - SPK data: ephemeris data for any body over the
        time period defined by the confinement window must be
        loaded. If aberration corrections are used, the states of
        target and observer relative to the solar system barycenter
        must be calculable from the available ephemeris data.
        Typically ephemeris data are made available by loading one
        or more SPK files via furnsh_c.

      - If non-inertial reference frames are used, then PCK
        files, frame kernels, C-kernels, and SCLK kernels may be
        needed.

   In all cases, kernel data are normally loaded once per program
   run, NOT every time this routine is called.

-Particulars

   This routine provides a simpler, but less flexible interface
   than does the routine zzgfrel_ for conducting searches for events
   corresponding to an arbitrary user defined scalar quantity 
   function. Applications that require support for progress 
   reporting, interrupt handling, non-default step or refinement
   functions, or non-default convergence tolerance should call
   zzgfrel_ rather than this routine.

   This routine determines a set of one or more time intervals
   within the confinement window when the  scalar function
   satisfies a caller-specified constraint. The resulting set of
   intervals is returned as a SPICE window.

   udqdec Default Template
   =======================

   The user must supply a routine to determine whether sign of the
   time derivative of udfunc is positive or negative at 'et'. For
   cases where udfunc is numerically well behaved, the user
   may find it convenient to use a routine based on the below
   template. uddc_c determines the truth of the expression

      d (udfunc)
      --         < 0
      dt

   using the library routine uddf_c to numerically calculate the
   derivative of udfunc using a three-point estimation. Use
   of gfdecr requires only changing the "udfunc" argument
   to that of the user provided scalar function passed to gfuds_c
   and defining the differential interval size, 'dt'. Please see 
   the Examples section for an example of gfdecr use.

   void gfdecr ( SpiceDouble et, SpiceBoolean * isdecr )
      {

      SpiceDouble         dt = h, double precision interval size;

      uddc_c( udfunc, uddf_c, et, dt, isdecr );

      return;
      }

   Below we discuss in greater detail aspects of this routine's
   solution process that are relevant to correct and efficient
   use of this routine in user applications.

   The Search Process
   ==================
   
   Regardless of the type of constraint selected by the caller, this
   routine starts the search for solutions by determining the time
   periods, within the confinement window, over which the specified
   scalar function is monotone increasing and monotone
   decreasing. Each of these time periods is represented by a SPICE
   window. Having found these windows, all of the quantity
   function's local extrema within the confinement window are known.
   Absolute extrema then can be found very easily. 
   
   Within any interval of these "monotone" windows, there will be at
   most one solution of any equality constraint. Since the boundary
   of the solution set for any inequality constraint is the set 
   of points where an equality constraint is met, the solutions of
   both equality and inequality constraints can be found easily
   once the monotone windows have been found.

   Step Size
   =========

   The monotone windows (described above) are found using a two-step
   search process. Each interval of the confinement window is
   searched as follows: first, the input step size is used to
   determine the time separation at which the sign of the rate of
   change of quantity function will be sampled. Starting at
   the left endpoint of an interval, samples will be taken at each
   step. If a change of sign is found, a root has been bracketed; at
   that point, the time at which the time derivative of the quantity 
   function is zero can be found by a refinement process, for 
   example, using a binary search.
   
   Note that the optimal choice of step size depends on the lengths
   of the intervals over which the quantity function is monotone:
   the step size should be shorter than the shortest of these
   intervals (within the confinement window).
   
   The optimal step size is *not* necessarily related to the lengths
   of the intervals comprising the result window. For example, if
   the shortest monotone interval has length 10 days, and if the
   shortest result window interval has length 5 minutes, a step size
   of 9.9 days is still adequate to find all of the intervals in the
   result window. In situations like this, the technique of using
   monotone windows yields a dramatic efficiency improvement over a
   state-based search that simply tests at each step whether the
   specified constraint is satisfied. The latter type of search can
   miss solution intervals if the step size is shorter than the
   shortest solution interval.

   Having some knowledge of the relative geometry of the targets and 
   observer can be a valuable aid in picking a reasonable step size. 
   In general, the user can compensate for lack of such knowledge by 
   picking a very short step size; the cost is increased computation 
   time. 

   Note that the step size is not related to the precision with which
   the endpoints of the intervals of the result window are computed.
   That precision level is controlled by the convergence tolerance.
   
   
   Convergence Tolerance
   =====================

   Once a root has been bracketed, a refinement process is used to 
   narrow down the time interval within which the root must lie. 
   This refinement process terminates when the location of the root 
   has been determined to within an error margin called the 
   "convergence tolerance." The convergence tolerance used by this 
   routine is set via the parameter SPICE_GF_CNVTOL. 

   The value of SPICE_GF_CNVTOL is set to a "tight" value so that the 
   tolerance doesn't become the limiting factor in the accuracy of 
   solutions found by this routine. In general the accuracy of input 
   data will be the limiting factor. 
   
   Making the tolerance tighter than SPICE_GF_CNVTOL is unlikely to 
   be useful, since the results are unlikely to be more accurate. 
   Making the tolerance looser will speed up searches somewhat, 
   since a few convergence steps will be omitted. However, in most 
   cases, the step size is likely to have a much greater affect 
   on processing time than would the convergence tolerance.


   The Confinement Window 
   ====================== 
   
   The simplest use of the confinement window is to specify a time 
   interval within which a solution is sought. However, the 
   confinement window can, in some cases, be used to make searches 
   more efficient. Sometimes it's possible to do an efficient search 
   to reduce the size of the time period over which a relatively 
   slow search of interest must be performed. 

-Examples

   The numerical results shown for these examples may differ across
   platforms. The results depend on the SPICE kernels used as
   input, the compiler and supporting libraries, and the machine 
   specific arithmetic implementation. 

   Conduct a search on the range-rate of the vector from the Sun
   to the Moon. Define a function to calculate the value.

   Use the meta-kernel shown below to load the required SPICE
   kernels.

         KPL/MK

         File name: standard.tm

         This meta-kernel is intended to support operation of SPICE
         example programs. The kernels shown here should not be
         assumed to contain adequate or correct versions of data
         required by SPICE-based user applications.

         In order for an application to use this meta-kernel, the
         kernels referenced here must be present in the user's
         current working directory.


         \begindata

            KERNELS_TO_LOAD = ( 'de414.bsp',
                                'pck00008.tpc',
                                'naif0009.tls'  )

         \begintext

   Code:

   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>

   #include "SpiceUsr.h"
   #include "SpiceZfc.h"
   #include "SpiceZad.h"


   #define       MAXWIN    20000
   #define       TIMFMT    "YYYY-MON-DD HR:MN:SC.###"
   #define       TIMLEN    41
   #define       NLOOPS    7

   void    gfq     ( SpiceDouble et, SpiceDouble * value );
   void    gfdecrx ( void ( * udfunc ) ( SpiceDouble    et,
                                         SpiceDouble  * value ),
                     SpiceDouble    et, 
                     SpiceBoolean * isdecr );

   doublereal dvnorm_(doublereal *state);


   int main( int argc, char **argv )
      {

      /.
      Create the needed windows. Note, one interval
      consists of two values, so the total number
      of cell values to allocate is twice
      the number of intervals.
      ./
      SPICEDOUBLE_CELL ( result, 2*MAXWIN );
      SPICEDOUBLE_CELL ( cnfine, 2        );

      SpiceDouble       begtim;
      SpiceDouble       endtim;
      SpiceDouble       step;
      SpiceDouble       adjust;
      SpiceDouble       refval;
      SpiceDouble       beg;
      SpiceDouble       end;

      SpiceChar         begstr [ TIMLEN ];
      SpiceChar         endstr [ TIMLEN ];
      
      SpiceInt          count;
      SpiceInt          i;
      SpiceInt          j;

      ConstSpiceChar * relate [NLOOPS] = { "=",
                                           "<",
                                           ">",
                                           "LOCMIN",
                                           "ABSMIN",
                                           "LOCMAX",
                                           "ABSMAX"
                                         };

      printf( "Compile date %s, %s\n\n", __DATE__, __TIME__ );

      /.  
      Load kernels.
      ./
      furnsh_c( "standard.tm" );
   
      /.  
      Store the time bounds of our search interval in the 'cnfine' 
      confinement window.
      ./
      str2et_c( "2007 JAN 01", &begtim );
      str2et_c( "2007 APR 01", &endtim );
   
      wninsd_c ( begtim, endtim, &cnfine );

      /.  
      Search using a step size of 1 day (in units of seconds). The reference
      value is .3365 km/s. We're not using the adjustment feature, so
      we set 'adjust' to zero.
      ./
      step   = spd_c();
      adjust = 0.;
      refval = .3365;

      for ( j = 0;  j < NLOOPS;  j++ )
         {

         printf ( "Relation condition: %s \n",  relate[j] );

         /.
         Perform the search. The SPICE window 'result' contains 
         the set of times when the condition is met. 
         ./

         gfuds_c ( gfq, 
                   gfdecrx,
                   relate[j],
                   refval,
                   adjust,
                   step,
                   MAXWIN,
                   &cnfine,
                   &result );

         count = wncard_c( &result );

         /.
         Display the results.
         ./
         if (count == 0 ) 
            {
            printf ( "Result window is empty.\n\n" );
            }
         else
            {
            for ( i = 0;  i < count;  i++ )
               {

               /.
               Fetch the endpoints of the Ith interval
               of the result window.
               ./
               wnfetd_c ( &result, i, &beg, &end );

               timout_c ( beg, TIMFMT, TIMLEN, begstr ); 
               timout_c ( end, TIMFMT, TIMLEN, endstr );

               printf ( "Start time, drdt = %s \n", begstr );
               printf ( "Stop time,  drdt = %s \n", endstr );

               }
               
            }

         printf("\n");
         
         }

      kclear_c();
      return( 0 );
      }



   /.
   The user defined functions required by GFUDS.
      
      gfq    for udfunc
      gfdecr for udqdec
   ./



   /.
   -Procedure Procedure gfq
   ./

   void gfq ( SpiceDouble et, SpiceDouble * value )

   /.
   -Abstract

      User defined geometric quantity function. In this case,
      the range from the sun to the Moon at TDB time 'et'.
   
   ./
      {
      
      /. Initialization ./
      SpiceInt             targ   = 301;
      SpiceInt             obs    = 10;

      SpiceChar          * ref    = "J2000";
      SpiceChar          * abcorr = "NONE";

      SpiceDouble          state [6];
      SpiceDouble          lt;

      /.
      Retrieve the vector from the Sun to the Moon in the J2000 
      frame, without aberration correction.
      ./
      spkez_c ( targ, et, ref, abcorr, obs, state, &lt );

      /.
      Calculate the scalar range rate corresponding the
     'state' vector.   
      ./

      *value = dvnorm_( state );

      return;
      }



   /.
   -Procedure gfdecrx
   ./
   
   void gfdecrx ( void ( * udfunc ) ( SpiceDouble    et,
                                      SpiceDouble  * value ),
                  SpiceDouble    et, 
                  SpiceBoolean * isdecr )

   /.
   -Abstract

      User defined function to detect if the function derivative
      is negative (the function is decreasing) at TDB time 'et'.
   ./
      {
         
      SpiceDouble         dt = 10.;
     
      /.
      Determine if "udfunc" is decreasing at 'et'.

      uddc_c - the GF function to determine if
                 the derivative of the user defined
                 function is negative at 'et'.

      uddf_c   - the SPICE function to numerically calculate the 
                 derivative of 'udfunc' at 'et' for the 
                 interval [et-dt, et+dt].
      ./

      uddc_c( udfunc, et, dt, isdecr );

      return;
      }


   The program outputs:

      Relation condition: = 
      Start time, drdt = 2007-JAN-02 00:35:19.574 
      Stop time,  drdt = 2007-JAN-02 00:35:19.574 
      Start time, drdt = 2007-JAN-19 22:04:54.899 
      Stop time,  drdt = 2007-JAN-19 22:04:54.899 
      Start time, drdt = 2007-FEB-01 23:30:13.428 
      Stop time,  drdt = 2007-FEB-01 23:30:13.428 
      Start time, drdt = 2007-FEB-17 11:10:46.540 
      Stop time,  drdt = 2007-FEB-17 11:10:46.540 
      Start time, drdt = 2007-MAR-04 15:50:19.929 
      Stop time,  drdt = 2007-MAR-04 15:50:19.929 
      Start time, drdt = 2007-MAR-18 09:59:05.959 
      Stop time,  drdt = 2007-MAR-18 09:59:05.959 
      
      Relation condition: < 
      Start time, drdt = 2007-JAN-02 00:35:19.574 
      Stop time,  drdt = 2007-JAN-19 22:04:54.899 
      Start time, drdt = 2007-FEB-01 23:30:13.428 
      Stop time,  drdt = 2007-FEB-17 11:10:46.540 
      Start time, drdt = 2007-MAR-04 15:50:19.929 
      Stop time,  drdt = 2007-MAR-18 09:59:05.959 
      
      Relation condition: > 
      Start time, drdt = 2007-JAN-01 00:00:00.000 
      Stop time,  drdt = 2007-JAN-02 00:35:19.574 
      Start time, drdt = 2007-JAN-19 22:04:54.899 
      Stop time,  drdt = 2007-FEB-01 23:30:13.428 
      Start time, drdt = 2007-FEB-17 11:10:46.540 
      Stop time,  drdt = 2007-MAR-04 15:50:19.929 
      Start time, drdt = 2007-MAR-18 09:59:05.959 
      Stop time,  drdt = 2007-APR-01 00:00:00.000 
      
      Relation condition: LOCMIN 
      Start time, drdt = 2007-JAN-11 07:03:58.988 
      Stop time,  drdt = 2007-JAN-11 07:03:58.988 
      Start time, drdt = 2007-FEB-10 06:26:15.439 
      Stop time,  drdt = 2007-FEB-10 06:26:15.439 
      Start time, drdt = 2007-MAR-12 03:28:36.404 
      Stop time,  drdt = 2007-MAR-12 03:28:36.404 
      
      Relation condition: ABSMIN 
      Start time, drdt = 2007-JAN-11 07:03:58.988 
      Stop time,  drdt = 2007-JAN-11 07:03:58.988 
      
      Relation condition: LOCMAX 
      Start time, drdt = 2007-JAN-26 02:27:33.766 
      Stop time,  drdt = 2007-JAN-26 02:27:33.766 
      Start time, drdt = 2007-FEB-24 09:35:07.816 
      Stop time,  drdt = 2007-FEB-24 09:35:07.816 
      Start time, drdt = 2007-MAR-25 17:26:56.150 
      Stop time,  drdt = 2007-MAR-25 17:26:56.150 
      
      Relation condition: ABSMAX 
      Start time, drdt = 2007-MAR-25 17:26:56.150 
      Stop time,  drdt = 2007-MAR-25 17:26:56.150 

-Restrictions

   1) Any kernel files required by this routine must be loaded
      before this routine is called.

-Literature_References

   None.

-Author_and_Institution

   N.J. Bachman   (JPL)
   E.D. Wright    (JPL)
 
-Version

   -CSPICE Version 1.0.0, 22-FEB-2010 (EDW) 

-Index_Entries

   GF user defined scalar function search

-&
*/

  { /* Begin gfuds_c */

   /*
   Local variables 
   */
   
   doublereal              * work;

   static SpiceInt           nw = SPICE_GF_NWMAX;

   SpiceInt                  nBytes;


   /*
   Participate in error tracing.
   */
   if ( return_c() )
     {
      return;
      }
   chkin_c ( "gfuds_c" );


   /*
   Make sure cell data types are d.p. 
   */
   CELLTYPECHK2 ( CHK_STANDARD, "gfuds_c", SPICE_DP, cnfine, result );

   /* 
   Initialize the input cells if necessary. 
   */
   CELLINIT2 ( cnfine, result );

   /*
   Check the other input strings to make sure each pointer is non-null 
   and each string length is non-zero.
   */
   CHKFSTR ( CHK_STANDARD, "gfuds_c", relate );

   /*
   Store the input function pointers so these functions can be
   called by the GF adapters. 
   */
   zzadsave_c ( UDFUNC,  (void *)(udfunc)  );
   zzadsave_c ( UDQDEC,  (void *)(udqdec)  );

   /*
   Check the workspace size; some mallocs have a violent
   dislike for negative allocation amounts. To be safe,
   rule out a count of zero intervals as well.
   */

   if ( nintvls < 1 )
      {
      setmsg_c ( "The specified workspace interval count # was "
                 "less than the minimum allowed value of one (1)." );
      errint_c ( "#",  nintvls                              );
      sigerr_c ( "SPICE(VALUEOUTOFRANGE)"                   );
      chkout_c ( "gfuds_c"                                  );
      return;
      } 
      

   /*
   Allocate the workspace. 'nintvls' indicates the maximum number of
   intervals returned in 'result'. An interval consists of
   two values.
   */

   nintvls = 2 * nintvls;
   
   nBytes = (nintvls + SPICE_CELL_CTRLSZ ) * nw * sizeof(SpiceDouble);

   work   = (doublereal *) alloc_SpiceMemory( nBytes );

   if ( !work ) 
      {
      setmsg_c ( "Workspace allocation of # bytes failed due to "
                 "malloc failure"                               );
      errint_c ( "#",  nBytes                                   );
      sigerr_c ( "SPICE(MALLOCFAILED)"                          );
      chkout_c ( "gfuds_c"                                      );
      return;
      }


   /*
   Let the f2c'd routine do the work. 

   We pass the adapter functions, not those provided as inputs,
   to the f2c'd routine:

      zzadfunc_c  adapter for  udfunc
      zzadqdec_c     ''        udqdec

   */

   (void) gfuds_( ( U_fp            ) zzadfunc_c,
                  ( U_fp            ) zzadqdec_c,
                  ( char          * ) relate,
                  ( doublereal    * ) &refval,
                  ( doublereal    * ) &adjust,
                  ( doublereal    * ) &step,
                  ( doublereal    * ) (cnfine->base),
                  ( integer       * ) &nintvls,
                  ( integer       * ) &nw,
                  ( doublereal    * ) work,
                  ( doublereal    * ) (result->base),
                  ( ftnlen          ) strlen(relate) );


   /*
   Always free dynamically allocated memory.
   */
   free_SpiceMemory( work );

   /*
   Sync the output cell.
   */
   if ( !failed_c() )
     {
     zzsynccl_c ( F2C, result );
     }

   ALLOC_CHECK;

   chkout_c ( "gfuds_c" );

   } /* End gfuds_c */
Ejemplo n.º 26
0
   void dafac_c ( SpiceInt      handle,
                  SpiceInt      n,
                  SpiceInt      lenvals,
                  const void  * buffer  ) 

/*

-Brief_I/O
 
   Variable  I/O  Description 
   --------  ---  -------------------------------------------------- 
   handle     I    handle of a DAF opened with write access. 
   n          I    Number of comments to put into the comment area. 
   lenvals    I    Length of elements
   buffer     I    Buffer of comments to put into the comment area. 
 
-Detailed_Input
 
   handle   is the file handle of a binary DAF which has been opened 
            with write access. 
 
   n        is the number of rows in the array `buffer'.  This is
            also the number of comment lines in `buffer' that are to be
            added to the comment area of the binary DAF attached to
            `handle'.
 
   buffer   A string buffer containing comments which are to be added 
            to the comment area of the binary DAF attached to `handle'. 
            buffer should be declared by the caller has follows:

               SpiceChar    buffer[n][lenvals];
            
            Each row of the buffer should contain one comment line.

-Detailed_Output
 
   None. 
 
-Parameters
 
   None. 
 
-Exceptions
 
   1) If the number of comments to be added is not positive, the 
      error SPICE(INVALIDARGUMENT) will be signaled. 
 
   2) If a non printing ASCII character is encountered in the 
      comments, the error SPICE(ILLEGALCHARACTER) will be signaled.
 
   3) If the binary DAF file attached to HANDLE is not open with 
      write access an error will be signalled by a routine called by
      this routine.
 
   4) If the end of the comments cannot be found, i.e., the end of 
      comments marker is missing on the last comment record, the error
      SPICE(BADCOMMENTAREA) will be signaled.
 
   5) If the input pointer `buffer' is null, the error
      SPICE(NULLPOINTER) will be signaled.
  
   6) If the input buffer string length indicated by `lenvals' 
      is less than 2, the error SPICE(STRINGTOOSHORT) will be signaled. 

-Files
 
   See argument `handle' in $ Detailed_Input. 
 
-Particulars
 
   A binary DAF contains a data area which is reserved for storing
   annotations or descriptive textual information about the data
   contained in a file. This area is referred to as the ``comment
   area'' of the file. The comment area of a DAF is a line oriented
   medium for storing textual information. The comment area preserves
   leading or embedded white space in the line(s) of text which are
   stored so that the appearance of the information will be unchanged
   when it is retrieved (extracted) at some other time. Trailing
   blanks, however, are NOT preserved, due to the way that character
   strings are represented in standard Fortran 77.
 
   This routine will take a buffer of text lines and add (append) them
   to the comment area of a binary DAF. If there are no comments in the
   comment area of the file, then space will be allocated and the text
   lines in `buffer' will be placed into the comment area. The text lines
   may contain only printable ASCII characters (decimal values 32 -
   126).
 
   There is NO maximum length imposed on the significant portion of a
   text line that may be placed into the comment area of a DAF. The
   maximum length of a line stored in the comment area should be
   reasonable, however, so that they may be easily extracted. A good
   maximum value for this would be 255 characters, as this can easily
   accommodate ``screen width'' lines as well as long lines which may
   contain some other form of information.
 
-Examples
 
   1) Let 
 
         handle   be the handle for a DAF which has been opened with 
                  write access. 
 
         n        be the number of lines of text to be added to the 
                  comment area of the binary DAF attached to handle. 
 
         lenvals  be the length of the rows of a string buffer.

         buffer   is an array of text lines to be added to the comment 
                  area of the binary DAF attached to handle. `buffer'
                  normally is declared

                     SpiceChar buffer [n][lenvals];
                  
      The call 
 
         dafac_c ( handle, n, lenvals, buffer );
 
      will append the first n line(s) in `buffer' to the comment area 
      of the binary DAF attached to `handle'. 
 
-Restrictions
 
   1) This routine uses constants that are specific to the ASCII 
      character sequence. The results of using this routine with 
      a different character sequence are unpredictable. 
 
   2) This routine is only used to extract records on environments 
      whose characters are a single byte in size.  Updates to this 
      routine and routines in its call tree may be required to 
      properly handle other cases. 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman   (JPL)
   K.R. Gehringer (JPL) 
 
-Version
 
   -CSPICE Version 1.0.0, 16-NOV-2006 (NJB) (KRG)

-Index_Entries
 
   add comments to a binary daf file 
   append comments to a daf file comment area 
 
-&
*/

{ /* Begin dafac_c */


   /*
   Local variables
   */
   SpiceChar             * fCvalsArr;
   
   SpiceInt                fCvalsLen;


   /*
   Participate in error tracing.
   */
   chkin_c ( "dafac_c" );


   /*
   Make sure the input string pointer for the `buffer' array is non-null 
   and that the length lenvals is sufficient.  
   */
   CHKOSTR ( CHK_STANDARD, "dafac_c", buffer, lenvals );
   
   /*
   The input buffer contains C-style strings; we must pass a 
   Fortran-style buffer to dafac_.
   */
   C2F_MapStrArr ( "dafac_c", 
                   n, lenvals, buffer, &fCvalsLen, &fCvalsArr );

   if ( failed_c() )
   {
      chkout_c ( "dafac_c" );
      return;
   }


   /*
   Call the f2c'd routine.
   */
   dafac_ ( ( integer * ) &handle,
            ( integer * ) &n,
            ( char    * ) fCvalsArr,
            ( ftnlen    ) fCvalsLen );

   /*
   Free the dynamically allocated array.
   */
   free ( fCvalsArr );


   chkout_c ( "dafac_c" );

} /* End dafac_c */
Ejemplo n.º 27
0
   void ckcov_c ( ConstSpiceChar    * ck,
                  SpiceInt            idcode,
                  SpiceBoolean        needav,
                  ConstSpiceChar    * level,
                  SpiceDouble         tol,
                  ConstSpiceChar    * timsys,
                  SpiceCell         * cover   ) 
/*

-Brief_I/O
 
   Variable  I/O  Description 
   --------  ---  -------------------------------------------------- 
   ck         I   Name of CK file. 
   idcode     I   ID code of object. 
   needav     I   Flag indicating whether angular velocity is needed. 
   level      I   Coverage level:  "SEGMENT" OR "INTERVAL". 
   tol        I   Tolerance in ticks. 
   timsys     I   Time system used to represent coverage. 
   cover     I/O  Window giving coverage for `idcode'. 
 
-Detailed_Input
 
   ck             is the name of a C-kernel. 
    
   idcode         is the integer ID code of an object, normally a
                  spacecraft structure or instrument, for which
                  pointing data are expected to exist in the specified
                  CK file.
 
   needav         is a logical variable indicating whether only
                  segments having angular velocity are to be considered
                  when determining coverage.  When `needav' is
                  SPICETRUE, segments without angular velocity don't
                  contribute to the coverage window; when `needav' is
                  SPICEFALSE, all segments for `idcode' may contribute
                  to the coverage window.
 
 
   level          is the level (granularity) at which the coverage 
                  is examined.  Allowed values and corresponding 
                  meanings are: 
 
                     "SEGMENT"    The output coverage window contains
                                  intervals defined by the start and
                                  stop times of segments for the object
                                  designated by `idcode'.
 
                     "INTERVAL"   The output coverage window contains
                                  interpolation intervals of segments
                                  for the object designated by
                                  `idcode'.  For type 1 segments, which
                                  don't have interpolation intervals,
                                  each epoch associated with a pointing
                                  instance is treated as a singleton
                                  interval; these intervals are added
                                  to the coverage window.

                                  All interpolation intervals are
                                  considered to lie within the segment
                                  bounds for the purpose of this
                                  summary:  if an interpolation
                                  interval extends beyond the segment
                                  coverage interval, only its
                                  intersection with the segment
                                  coverage interval is considered to
                                  contribute to the total coverage.
 
   tol            is a tolerance value expressed in ticks of the
                  spacecraft clock associated with IDCODE.  Before each
                  interval is inserted into the coverage window, the
                  interval is intersected with the segment coverage
                  interval, then if the intersection is non-empty, it
                  is expanded by `tol': the left endpoint of the
                  intersection interval is reduced by `tol' and the
                  right endpoint is increased by `tol'. Adjusted
                  interval endpoints, when expressed as encoded SCLK,
                  never are less than zero ticks.  Any intervals that
                  overlap as a result of the expansion are merged.
 
                  The coverage window returned when tol > 0 indicates
                  the coverage provided by the file to the CK readers
                  ckgpav_c and ckgp_c when that value of `tol' is
                  passed to them as an input.
 
               
   timsys         is a string indicating the time system used in the
                  output coverage window.  `timsys' may have the
                  values:
  
                      "SCLK"    Elements of `cover' are expressed in 
                                encoded SCLK ("ticks"), where the 
                                clock is associated with the object 
                                designated by `idcode'. 
 
                      "TDB"     Elements of `cover' are expressed as 
                                seconds past J2000 TDB. 
 
 
   cover          is an initialized CSPICE window data structure.
                  `cover' optionally may contain coverage data on
                  input; on output, the data already present in `cover'
                  will be combined with coverage found for the object
                  designated by `idcode' in the file `ck'.
 
                  If `cover' contains no data on input, its size and
                  cardinality still must be initialized.
 
-Detailed_Output
 
   cover          is a CSPICE window data structure which represents
                  the merged coverage for `idcode'. When the coverage
                  level is "INTERVAL", this is the set of time
                  intervals for which data for `idcode' are present in
                  the file `ck', merged with the set of time intervals
                  present in `cover' on input.  The merged coverage is
                  represented as the union of one or more disjoint time
                  intervals.  The window `cover' contains the pairs of
                  endpoints of these intervals.
 
                  When the coverage level is "SEGMENT", `cover' is
                  computed in a manner similar to that described above,
                  but the coverage intervals used in the computation
                  are those of segments rather than interpolation
                  intervals within segments.  
 
                  When `tol' is > 0, the intervals comprising the
                  coverage window for `idcode' are expanded by `tol'
                  and any intervals overlapping as a result are merged.
                  The resulting window is returned in `cover'. The
                  expanded window in no case extends beyond the segment
                  bounds in either direction by more than `tol'.
 
                  The interval endpoints contained in `cover' are
                  encoded spacecraft clock times if `timsys' is "SCLK";
                  otherwise the times are converted from encoded
                  spacecraft clock to seconds past J2000 TDB.
 
                  See the Examples section below for a complete example
                  program showing how to retrieve the endpoints from
                  `cover'.
                                     
-Parameters
 
   None. 
 
-Exceptions
 
   1)  If the input file has transfer format, the error  
       SPICE(INVALIDFORMAT) is signaled. 
 
   2)  If the input file is not a transfer file but has architecture 
       other than DAF, the error SPICE(BADARCHTYPE) is signaled. 
 
   3)  If the input file is a binary DAF file of type other than 
       CK, the error SPICE(BADFILETYPE) is signaled. 
 
   4)  If the CK file cannot be opened or read, the error will 
       be diagnosed by routines called by this routine. The output 
       window will not be modified. 
 
   5)  If the size of the output window argument `cover' is 
       insufficient to contain the actual number of intervals in the 
       coverage window for `idcode', the error will be diagnosed by 
       routines called by this routine.   
 
   6)  If `tol' is negative, the error SPICE(VALUEOUTOFRANGE) is 
       signaled. 
 
   7)  If `level' is not recognized, the error SPICE(INVALIDOPTION) 
       is signaled. 
 
   8)  If `timsys' is not recognized, the error SPICE(INVALIDOPTION) 
       is signaled. 
 
   9)  If a time conversion error occurs, the error will be  
       diagnosed by a routine in the call tree of this routine. 
 
   10) If the output time system is TDB, the CK subsystem must be 
       able to map `idcode' to the ID code of the associated 
       spacecraft clock.  If this mapping cannot be performed, the 
       error will be diagnosed by a routine in the call tree of this 
       routine. 
  
   11) The error SPICE(EMPTYSTRING) is signaled if any of the input
       strings `ck', `level', or `timsys' do not contain at least one
       character, since such an input string cannot be converted to a
       Fortran-style string in this case.
      
   12) The error SPICE(NULLPOINTER) is signaled if the if any of the input
       strings `ck', `level', or `timsys' are null.


-Files
 
   This routine reads a C-kernel. 
 
   If the output time system is "TDB", then a leapseconds kernel 
   and an SCLK kernel for the spacecraft clock associated with 
   `idcode' must be loaded before this routine is called. 
 
   If the ID code of the clock associated with `idcode' is not  
   equal to  
 
      idcode / 1000 
 
   then the kernel variable  
 
      CK_<idcode>_SCLK 
  
   must be present in the kernel pool to identify the clock 
   associated with `idcode'.  This variable must contain the ID code 
   to be used for conversion between SCLK and TDB. Normally this 
   variable is provided in a text kernel loaded via furnsh_c. 
 
-Particulars
 
   This routine provides an API via which applications can determine 
   the coverage a specified CK file provides for a specified 
   object. 
 
-Examples
 
   1)  Display the interval-level coverage for each object in a
       specified CK file. Use tolerance of zero ticks. Do not request
       angular velocity. Express the results in the TDB time system.
 
       Find the set of objects in the file. Loop over the contents of
       the ID code set:  find the coverage for each item in the set and
       display the coverage.


          #include <stdio.h>
          #include "SpiceUsr.h"

          int main()
          {

             /.
             Local parameters
             ./
             #define  FILSIZ         256
             #define  MAXIV          100000
             #define  WINSIZ         ( 2 * MAXIV )
             #define  TIMLEN         51
             #define  MAXOBJ         1000

             /.
             Local variables
             ./
             SPICEDOUBLE_CELL        ( cover, WINSIZ );
             SPICEINT_CELL           ( ids,   MAXOBJ );

             SpiceChar               ck      [ FILSIZ ];
             SpiceChar               lsk     [ FILSIZ ];
             SpiceChar               sclk    [ FILSIZ ];
             SpiceChar               timstr  [ TIMLEN ];

             SpiceDouble             b;
             SpiceDouble             e;

             SpiceInt                i;
             SpiceInt                j;
             SpiceInt                niv;
             SpiceInt                obj;


             /.
             Load a leapseconds kernel and SCLK kernel for output time
             conversion.  Note that we assume a single spacecraft clock is
             associated with all of the objects in the CK.
             ./
             prompt_c ( "Name of leapseconds kernel > ", FILSIZ, lsk );
             furnsh_c ( lsk );

             prompt_c ( "Name of SCLK kernel        > ", FILSIZ, sclk );
             furnsh_c ( sclk );

             /.
             Get name of CK file.
             ./
             prompt_c ( "Name of CK file            > ", FILSIZ, ck );

             /.
             Find the set of objects in the CK file. 
             ./
             ckobj_c ( ck, &ids );

             /.
             We want to display the coverage for each object. Loop over
             the contents of the ID code set, find the coverage for
             each item in the set, and display the coverage.
             ./
             for ( i = 0;  i < card_c( &ids );  i++  )
             {
                /.
                Find the coverage window for the current object. 
                Empty the coverage window each time so we don't
                include data for the previous object.
                ./
                obj  =  SPICE_CELL_ELEM_I( &ids, i );

                scard_c ( 0,  &cover );  
                ckcov_c ( ck,          obj,  SPICEFALSE, 
                          "INTERVAL",  0.0,  "TDB",       &cover );

                /.
                Get the number of intervals in the coverage window.
                ./
                niv = wncard_c( &cover );

                /.
                Display a simple banner.
                ./
                printf ( "%s\n", "========================================" );

                printf ( "Coverage for object %ld\n", obj );

                /.
                Convert the coverage interval start and stop times to TDB
                calendar strings.
                ./
                for ( j = 0;  j < niv;  j++  )
                {
                   /.
                   Get the endpoints of the jth interval.
                   ./
                   wnfetd_c ( &cover, j, &b, &e );

                   /.
                   Convert the endpoints to TDB calendar
                   format time strings and display them.
                   ./
                   timout_c ( b, 
                              "YYYY MON DD HR:MN:SC.###### (TDB) ::TDB",  
                              TIMLEN,
                              timstr                                    );

                   printf ( "\n"
                            "Interval:  %ld\n"
                            "Start:     %s\n",
                            j,
                            timstr            );

                   timout_c ( e, 
                              "YYYY MON DD HR:MN:SC.###### (TDB) ::TDB",  
                              TIMLEN,
                              timstr                                    );
                   printf ( "Stop:      %s\n", timstr );

                }
                printf ( "%s\n", "========================================" );

             }
             return ( 0 );
          } 


   2)  Find the segment-level coverage for the object designated by
       IDCODE provided by the set of CK files loaded via a metakernel.
       (The metakernel must also specify leapseconds and SCLK kernels.)
       Use tolerance of zero ticks. Do not request angular velocity.
       Express the results in the TDB time system.
 

          #include <stdio.h>
          #include "SpiceUsr.h"

          int main()
          {

             /.
             Local parameters
             ./
             #define  FILSIZ         256
             #define  LNSIZE         81 
             #define  MAXCOV         100000
             #define  WINSIZ         ( 2 * MAXCOV )
             #define  TIMLEN         51

             /.
             Local variables
             ./
             SPICEDOUBLE_CELL        ( cover, WINSIZ );

             SpiceBoolean            found;

             SpiceChar               file    [ FILSIZ ];
             SpiceChar               idch    [ LNSIZE ];
             SpiceChar               meta    [ FILSIZ ];
             SpiceChar               source  [ FILSIZ ];
             SpiceChar               timstr  [ TIMLEN ];
             SpiceChar               type    [ LNSIZE ];

             SpiceDouble             b;
             SpiceDouble             e;

             SpiceInt                count;
             SpiceInt                handle;
             SpiceInt                i;
             SpiceInt                idcode;
             SpiceInt                niv;


             /.
             Prompt for the metakernel name; load the metakernel.
             The metakernel lists the CK files whose coverage
             for `idcode' we'd like to determine.  The metakernel
             must also specify a leapseconds kernel and an SCLK
             kernel for the clock associated with `idcode'.
             ./
             prompt_c ( "Name of metakernel > ", FILSIZ, meta );
             furnsh_c ( meta );

             /.
             Get the ID code of interest. 
             ./
             prompt_c ( "Enter ID code      > ", LNSIZE, idch );
             prsint_c ( idch,  &idcode );

             /.
             Find out how many kernels are loaded.  Loop over the
             kernels:  for each loaded CK file, add its coverage
             for `idcode', if any, to the coverage window.
             ./
             ktotal_c ( "CK", &count );

             for ( i = 0;  i < count;  i++  )
             {
                kdata_c  ( i,           "CK",     FILSIZ,  
                           LNSIZE,      FILSIZ,   file,  
                           type,        source,   &handle,     &found );

                ckcov_c  ( file,        idcode,   SPICEFALSE,
                           "SEGMENT",   0.0,      "TDB",       &cover );
             }

             /.
             Display results. 

             Get the number of intervals in the coverage window.
             ./
             niv = wncard_c( &cover );

             /.
             Display a simple banner.
             ./
             printf ( "\nCoverage for object %ld\n", idcode );

             /.
             Convert the coverage interval start and stop times to TDB
             calendar strings.
             ./
             for ( i = 0;  i < niv;  i++  )
             {
                /.
                Get the endpoints of the ith interval.
                ./
                wnfetd_c ( &cover, i, &b, &e );

                /.
                Convert the endpoints to TDB calendar
                format time strings and display them.
                ./
                timout_c ( b, 
                           "YYYY MON DD HR:MN:SC.###### (TDB) ::TDB",  
                           TIMLEN,
                           timstr                                  );

                printf ( "\n"
                         "Interval:  %ld\n"
                         "Start:     %s\n",
                         i,
                         timstr            );

                timout_c ( e, 
                           "YYYY MON DD HR:MN:SC.###### (TDB) ::TDB",  
                           TIMLEN,
                           timstr                                  );
                printf ( "Stop:      %s\n", timstr );

             }
             return ( 0 );
          }


-Restrictions
 
   1) When this routine is used to accumulate coverage for `idcode' 
      provided by multiple CK files, the inputs `needav', `level', `tol', 
      and `timsys'  must have the same values for all files in order 
      for the result to be meaningful. 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman   (JPL) 
 
-Version
 
   -CSPICE Version 1.0.1, 30-NOV-2007 (NJB)

       Corrected bug in first example program in header:
       program now empties result window prior to collecting
       data for each object. Updated examples to use wncard_c 
       rather than card_c. Updated second example to demonstrate
       segment-level summary capability.

   -CSPICE Version 1.0.0, 07-JAN-2005 (NJB)

-Index_Entries
 
   get coverage window for ck object 
 
-&
*/

{ /* Begin ckcov_c */


   /*
   Local variables 
   */
   logical                 need;


   /*
   Participate in error tracing.
   */
   if ( return_c() )
   {
      return; 
   }
   chkin_c ( "ckcov_c" );

   /*
   Check the input string `ck' to make sure the pointer is non-null 
   and the string length is non-zero.
   */
   CHKFSTR ( CHK_STANDARD, "ckcov_c", ck );
   
   /*
   Check the input string `level' to make sure the pointer is non-null 
   and the string length is non-zero.
   */
   CHKFSTR ( CHK_STANDARD, "ckcov_c", level );

   /*
   Check the input string `timsys' to make sure the pointer is non-null 
   and the string length is non-zero.
   */
   CHKFSTR ( CHK_STANDARD, "ckcov_c", timsys );

   /*
   Make sure cell data type is d.p. 
   */
   CELLTYPECHK ( CHK_STANDARD, "ckcov_c", SPICE_DP, cover );

   /*
   Initialize the cell if necessary. 
   */
   CELLINIT ( cover );   

   /*
   Call the f2c'd Fortran routine.
   */
   need = needav;

   ckcov_ ( ( char       * ) ck,
            ( integer    * ) &idcode,
            ( logical    * ) &need,
            ( char       * ) level,
            ( doublereal * ) &tol,
            ( char       * ) timsys,
            ( doublereal * ) (cover->base),
            ( ftnlen       ) strlen(ck),
            ( ftnlen       ) strlen(level),
            ( ftnlen       ) strlen(timsys)  );

   /*
   Sync the output cell. 
   */
   if ( !failed_c() )
   {
      zzsynccl_c ( F2C, cover );
   }

   chkout_c ( "ckcov_c" );

} /* End ckcov_c */
Ejemplo n.º 28
0
   void gfoclt_c ( ConstSpiceChar   * occtyp,
                   ConstSpiceChar   * front,
                   ConstSpiceChar   * fshape,
                   ConstSpiceChar   * fframe,
                   ConstSpiceChar   * back,
                   ConstSpiceChar   * bshape,
                   ConstSpiceChar   * bframe,
                   ConstSpiceChar   * abcorr,
                   ConstSpiceChar   * obsrvr,
                   SpiceDouble        step,
                   SpiceCell        * cnfine,
                   SpiceCell        * result )
/*

-Brief_I/O
 
   VARIABLE        I/O  DESCRIPTION 
   --------------- ---  -------------------------------------------------
   SPICE_GF_CNVTOL  P   Convergence tolerance. 
   occtyp           I   Type of occultation. 
   front            I   Name of body occulting the other. 
   fshape           I   Type of shape model used for front body. 
   fframe           I   Body-fixed, body-centered frame for front body. 
   back             I   Name of body occulted by the other. 
   bshape           I   Type of shape model used for back body. 
   bframe           I   Body-fixed, body-centered frame for back body. 
   abcorr           I   Aberration correction flag. 
   obsrvr           I   Name of the observing body. 
   step             I   Step size in seconds for finding occultation  
                        events. 
   cnfine          I-O  SPICE window to which the search is restricted. 
   result           O   SPICE window containing results. 
    
-Detailed_Input
 
 
   occtyp     indicates the type of occultation that is to be found. 
              Note that transits are considered to be a type of
              occultation.

              Supported values and corresponding definitions are: 
 
                 "FULL"               denotes the full occultation 
                                      of the body designated by  
                                      `back' by the body designated 
                                      by `front', as seen from 
                                      the location of the observer. 
                                      In other words, the occulted 
                                      body is completely invisible 
                                      as seen from the observer's 
                                      location. 
 
                 "ANNULAR"            denotes an annular 
                                      occultation: the body 
                                      designated by `front' blocks 
                                      part of, but not the limb of, 
                                      the body designated by `back', 
                                      as seen from the location of 
                                      the observer. 
 
                 "PARTIAL"            denotes a partial, non-annular
                                      occultation: the body designated
                                      by `front' blocks part, but not
                                      all, of the limb of the body
                                      designated by `back', as seen
                                      from the location of the
                                      observer.
 
                 "ANY"                denotes any of the above three 
                                      types of occultations: 
                                      "PARTIAL", "ANNULAR", or 
                                      "FULL". 
 
                                      "ANY" should be used to search 
                                      for times when the body  
                                      designated by `front' blocks 
                                      any part of the body designated 
                                      by `back'. 
 
                                      The option "ANY" must be used 
                                      if either the front or back 
                                      target body is modeled as 
                                      a point. 
 
              Case and leading or trailing blanks are not 
              significant in the string `occtyp'. 
 
 
   front      is the name of the target body that occults---that is, 
              passes in front of---the other. Optionally, you may 
              supply the integer NAIF ID code for the body as a 
              string. For example both "MOON" and "301" are 
              legitimate strings that designate the Moon. 
 
              Case and leading or trailing blanks are not 
              significant in the string `front'. 
 
 
   fshape     is a string indicating the geometric model used to
              represent the shape of the front target body. The
              supported options are:
 
                 "ELLIPSOID"     Use a triaxial ellipsoid model
                                 with radius values provided via the 
                                 kernel pool. A kernel variable  
                                 having a name of the form 
 
                                    "BODYnnn_RADII"  
 
                                 where nnn represents the NAIF 
                                 integer code associated with the 
                                 body, must be present in the kernel 
                                 pool. This variable must be 
                                 associated with three numeric 
                                 values giving the lengths of the 
                                 ellipsoid's X, Y, and Z semi-axes. 
 
                 "POINT"         Treat the body as a single point. 
                                 When a point target is specified, 
                                 the occultation type must be 
                                 set to "ANY". 
                                  
              At least one of the target bodies `front' and `back' must 
              be modeled as an ellipsoid. 
 
              Case and leading or trailing blanks are not 
              significant in the string `fshape'. 
 
 
   fframe     is the name of the body-fixed, body-centered reference 
              frame associated with the front target body. Examples 
              of such names are "IAU_SATURN" (for Saturn) and 
              "ITRF93" (for the Earth). 
 
              If the front target body is modeled as a point, `fframe' 
              should be left empty or blank. 
 
              Case and leading or trailing blanks bracketing a
              non-blank frame name are not significant in the string
              `fframe'.

 
   back       is the name of the target body that is occulted 
              by---that is, passes in back of---the other. 
              Optionally, you may supply the integer NAIF ID code 
              for the body as a string. For example both "MOON" and 
              "301" are legitimate strings that designate the Moon. 
 
              Case and leading or trailing blanks are not 
              significant in the string `back'. 
 
 
   bshape     is the shape specification for the body designated by
              `back'. The supported options are those for `fshape'. See
              the description of `fshape' above for details.
               
 
   bframe     is the name of the body-fixed, body-centered reference 
              frame associated with the ``back'' target body. 
              Examples of such names are "IAU_SATURN" (for Saturn) 
              and "ITRF93" (for the Earth). 
 
              If the back target body is modeled as a point, `bframe' 
              should be left empty or blank. 
 
              Case and leading or trailing blanks bracketing a 
              non-blank frame name are not significant in the string 
              `bframe'. 
 
 
   abcorr     indicates the aberration corrections to be applied to 
              the state of each target body to account for one-way 
              light time.  Stellar aberration corrections are 
              ignored if specified, since these corrections don't 
              improve the accuracy of the occultation determination. 
 
              See the header of the SPICE routine spkezr_c for a 
              detailed description of the aberration correction 
              options. For convenience, the options supported by 
              this routine are listed below: 
 
                 "NONE"     Apply no correction.    
 
                 "LT"       "Reception" case:  correct for 
                            one-way light time using a Newtonian 
                            formulation. 
 
                 "CN"       "Reception" case:  converged 
                            Newtonian light time correction. 
 
                 "XLT"      "Transmission" case:  correct for 
                            one-way light time using a Newtonian 
                            formulation. 
 
                 "XCN"      "Transmission" case:  converged 
                            Newtonian light time correction. 
 
              Case and blanks are not significant in the string 
              `abcorr'. 
 
 
   obsrvr     is the name of the body from which the occultation is 
              observed. Optionally, you may supply the integer NAIF 
              ID code for the body as a string. 
 
              Case and leading or trailing blanks are not 
              significant in the string `obsrvr'. 


   step       is the step size to be used in the search. `step' must 
              be shorter than any interval, within the confinement 
              window, over which the specified condition is met. In
              other words, `step' must be shorter than the shortest
              occultation event that the user wishes to detect; `step'
              must also be shorter than the shortest time interval
              between two occultation events that occur within the
              confinement window (see below). However, `step' must not
              be *too* short, or the search will take an unreasonable
              amount of time.
 
              The choice of `step' affects the completeness but not the
              precision of solutions found by this routine; the
              precision is controlled by the convergence tolerance. See
              the discussion of the parameter SPICE_GF_CNVTOL for
              details.
 
              `step' has units of TDB seconds.  
 
  
   cnfine     is a SPICE window that confines the time period over 
              which the specified search is conducted. `cnfine' may 
              consist of a single interval or a collection of  
              intervals.  
 
              The endpoints of the time intervals comprising `cnfine'
              are interpreted as seconds past J2000 TDB.
                
              See the Examples section below for a code example  
              that shows how to create a confinement window. 
 
 
-Detailed_Output
 
   cnfine     is the input confinement window, updated if necessary
              so the control area of its data array indicates the
              window's size and cardinality. The window data are
              unchanged.


   result     is a SPICE window representing the set of time 
              intervals, within the confinement period, when the 
              specified occultation occurs. 
 
              The endpoints of the time intervals comprising `result'
              are interpreted as seconds past J2000 TDB.

              If `result' is non-empty on input, its contents 
              will be discarded before gfoclt_c conducts its 
              search. 
 
-Parameters
  
   SPICE_GF_CNVTOL     

              is the convergence tolerance used for finding endpoints
              of the intervals comprising the result window.
              SPICE_GF_CNVTOL is used to determine when binary searches
              for roots should terminate: when a root is bracketed
              within an interval of length SPICE_GF_CNVTOL, the root is
              considered to have been found.
 
              The accuracy, as opposed to precision, of roots found 
              by this routine depends on the accuracy of the input 
              data. In most cases, the accuracy of solutions will be 
              inferior to their precision. 
 
              SPICE_GF_CNVTOL is declared in the header file
             
                 SpiceGF.h
 
-Exceptions
 
   1)  In order for this routine to produce correct results, 
       the step size must be appropriate for the problem at hand. 
       Step sizes that are too large may cause this routine to miss 
       roots; step sizes that are too small may cause this routine 
       to run unacceptably slowly and in some cases, find spurious 
       roots. 
 
       This routine does not diagnose invalid step sizes, except 
       that if the step size is non-positive, the error  
       SPICE(INVALIDSTEPSIZE) will be signaled. 
 
   2)  Due to numerical errors, in particular, 
 
          - Truncation error in time values 
          - Finite tolerance value 
          - Errors in computed geometric quantities 
 
       it is *normal* for the condition of interest to not always be 
       satisfied near the endpoints of the intervals comprising the 
       result window. 
 
       The result window may need to be contracted slightly by the 
       caller to achieve desired results. The SPICE window routine 
       wncond_c can be used to contract the result window. 
 
   3)  If name of either target or the observer cannot be translated 
       to a NAIF ID code, the error will be diagnosed by a routine 
       in the call tree of this routine. 
        
   4)  If the radii of a target body modeled as an ellipsoid cannot 
       be determined by searching the kernel pool for a kernel 
       variable having a name of the form 
 
          "BODYnnn_RADII"  
 
       where nnn represents the NAIF integer code associated with 
       the body, the error will be diagnosed by a routine in the 
       call tree of this routine. 
 
   5)  If either of the target bodies `front' or `back' coincides with 
       the observer body `obsrvr', the error will be diagnosed by a 
       routine in the call tree of this routine. 
 
   6)  If the body designated by `front' coincides with that 
       designated by `back', the error will be diagnosed by a routine 
       in the call tree of this routine. 
        
   7)  If either of the body model specifiers `fshape' or `bshape' 
       is not recognized, the error will be diagnosed by a routine 
       in the call tree of this routine. 
 
   8)  If both of the body model specifiers `fshape' and `bshape' 
       specify point targets, the error will be diagnosed by a 
       routine in the call tree of this routine. 
 
   9)  If a target body-fixed reference frame associated with a  
       non-point target is not recognized, the error will be 
       diagnosed by a routine in the call tree of this routine. 
 
   10) If a target body-fixed reference frame is not centered at 
       the corresponding target body,  the error will be 
       diagnosed by a routine in the call tree of this routine. 
 
   11) If the loaded kernels provide insufficient data to  
       compute any required state vector, the deficiency will 
       be diagnosed by a routine in the call tree of this routine. 
 
   12) If an error occurs while reading an SPK or other kernel file, 
       the error will be diagnosed by a routine in the call tree  
       of this routine. 
 
   13) If the output SPICE window `result' has insufficient capacity 
       to contain the number of intervals on which the specified 
       occultation condition is met, the error will be diagnosed 
       by a routine in the call tree of this routine. 
 
   14) If a point target is specified and the occultation 
       type is set to a valid value other than "ANY", the 
       error will be diagnosed by a routine in the call tree  
       of this routine. 
 
   15) Invalid occultation types will be diagnosed by a routine in
       the call tree of this routine.

   16) Invalid aberration correction specifications will be
       diagnosed by a routine in the call tree of this routine.

   17) If any input string argument pointer is null, the error
       SPICE(NULLPOINTER) will be signaled.

   18) If any input string argument, other than `fframe' or `bframe',
       is empty, the error SPICE(EMPTYSTRING) will be signaled.

-Files
 
   Appropriate SPICE kernels must be loaded by the calling program
   before this routine is called.
 
   The following data are required: 
 
      - SPK data: the calling application must load ephemeris data 
        for the target, source and observer that cover the time 
        period specified by the window `cnfine'. If aberration 
        corrections are used, the states of target and observer 
        relative to the solar system barycenter must be calculable 
        from the available ephemeris data. Typically ephemeris data 
        are made available by loading one or more SPK files via 
        furnsh_c. 
 
      - PCK data: bodies modeled as triaxial ellipsoids must have 
        semi-axis lengths provided by variables in the kernel pool. 
        Typically these data are made available by loading a text 
        PCK file via furnsh_c. 
 
      - FK data: if either of the reference frames designated by
        `bframe' or `fframe' are not built in to the SPICE system,
        one or more FKs specifying these frames must be loaded. 

   Kernel data are normally loaded once per program run, NOT every time
   this routine is called.
 
-Particulars
 
   This routine provides a simpler, but less flexible, interface 
   than does the CSPICE routine gfocce_c for conducting searches for 
   occultation events. Applications that require support for 
   progress reporting, interrupt handling, non-default step or 
   refinement functions, or non-default convergence tolerance should 
   call gfocce_c rather than this routine. 
 
   This routine determines a set of one or more time intervals 
   within the confinement window when a specified type of 
   occultation occurs. The resulting set of intervals is returned as 
   a SPICE window. 
 
   Below we discuss in greater detail aspects of this routine's 
   solution process that are relevant to correct and efficient 
   use of this routine in user applications. 
    
 
   The Search Process 
   ================== 
 
   The search for occultations is treated as a search for state 
   transitions: times are sought when the state of the `back' body 
   changes from "not occulted" to "occulted" or vice versa. 
 
   Step Size 
   ========= 
 
   Each interval of the confinement window is searched as follows:
   first, the input step size is used to determine the time separation
   at which the occultation state will be sampled. Starting at the left
   endpoint of the interval, samples of the occultation state will be
   taken at each step. If a state change is detected, a root has been
   bracketed; at that point, the "root"--the time at which the state
   change occurs---is found by a refinement process, for example, via
   binary search.
 
   Note that the optimal choice of step size depends on the lengths 
   of the intervals over which the occultation state is constant: 
   the step size should be shorter than the shortest occultation 
   duration and the shortest period between occultations, within 
   the confinement window. 
 
   Having some knowledge of the relative geometry of the targets and 
   observer can be a valuable aid in picking a reasonable step size. 
   In general, the user can compensate for lack of such knowledge by 
   picking a very short step size; the cost is increased computation 
   time. 
 
   Note that the step size is not related to the precision with which 
   the endpoints of the intervals of the result window are computed. 
   That precision level is controlled by the convergence tolerance. 
 
 
   Convergence Tolerance 
   ===================== 
 
   Once a root has been bracketed, a refinement process is used to
   narrow down the time interval within which the root must lie. This
   refinement process terminates when the location of the root has been
   determined to within an error margin called the "convergence
   tolerance." The convergence tolerance used by this routine is set
   via the parameter SPICE_GF_CNVTOL.
 
   The value of SPICE_GF_CNVTOL is set to a "tight" value so that the
   tolerance doesn't limit the accuracy of solutions found by this
   routine. In general the accuracy of input data will be the limiting
   factor.
 
   To use a different tolerance value, a lower-level GF routine such as
   gfocce_c must be called. Making the tolerance tighter than
   SPICE_GF_CNVTOL is unlikely to be useful, since the results are
   unlikely to be more accurate. Making the tolerance looser will speed
   up searches somewhat, since a few convergence steps will be omitted.
   However, in most cases, the step size is likely to have a much
   greater effect on processing time than would the convergence
   tolerance.
 
 
   The Confinement Window 
   ====================== 
 
   The simplest use of the confinement window is to specify a time 
   interval within which a solution is sought. 

   The confinement window also can be used to restrict a search to
   a time window over which required data (typically ephemeris
   data, in the case of occultation searches) are known to be
   available.

   In some cases, the confinement window be used to make searches
   more efficient. Sometimes it's possible to do an efficient search
   to reduce the size of the time period over which a relatively
   slow search of interest must be performed. See the "CASCADE"
   example program in gf.req for a demonstration.
 
-Examples
 
 
   The numerical results shown for these examples may differ across
   platforms. The results depend on the SPICE kernels used as
   input, the compiler and supporting libraries, and the machine
   specific arithmetic implementation.


   1) Find occultations of the Sun by the Moon (that is, solar
      eclipses) as seen from the center of the Earth over the month
      December, 2001.
 
      Use light time corrections to model apparent positions of Sun 
      and Moon. Stellar aberration corrections are not specified 
      because they don't affect occultation computations. 
 
      We select a step size of 3 minutes, which means we 
      ignore occultation events lasting less than 3 minutes, 
      if any exist. 
 
      Use the meta-kernel shown below to load the required SPICE
      kernels.

         KPL/MK

         File name: standard.tm

         This meta-kernel is intended to support operation of SPICE
         example programs. The kernels shown here should not be
         assumed to contain adequate or correct versions of data
         required by SPICE-based user applications.

         In order for an application to use this meta-kernel, the
         kernels referenced here must be present in the user's
         current working directory.


         \begindata

            KERNELS_TO_LOAD = ( 'de421.bsp',
                                'pck00008.tpc',
                                'naif0009.tls'  )

         \begintext
 
 

      Example code begins here.


         #include <stdio.h>
         #include "SpiceUsr.h"

         int main()
         {
            /.
            Local constants 
            ./

            #define TIMFMT          "YYYY MON DD HR:MN:SC.###### (TDB)::TDB"
            #define MAXWIN          200
            #define TIMLEN          41

            /.
            Local variables 
            ./
            SPICEDOUBLE_CELL      ( cnfine, MAXWIN );
            SPICEDOUBLE_CELL      ( result, MAXWIN );

            SpiceChar             * win0;
            SpiceChar             * win1;
            SpiceChar               begstr [ TIMLEN ];
            SpiceChar               endstr [ TIMLEN ];

            SpiceDouble             et0;
            SpiceDouble             et1;
            SpiceDouble             left;
            SpiceDouble             right;
            SpiceDouble             step;

            SpiceInt                i;

            /.
            Load kernels. 
            ./
            furnsh_c ( "standard.tm" );

            /.
            Obtain the TDB time bounds of the confinement
            window, which is a single interval in this case.
            ./
            win0 = "2001 DEC 01 00:00:00 TDB";
            win1 = "2002 JAN 01 00:00:00 TDB";

            str2et_c ( win0, &et0 );
            str2et_c ( win1, &et1 );

            /.
            Insert the time bounds into the confinement
            window.
            ./
            wninsd_c ( et0, et1, &cnfine );

            /.
            Select a 3-minute step. We'll ignore any occultations
            lasting less than 3 minutes.  Units are TDB seconds.
            ./
            step = 180.0;

            /.
            Perform the search.
            ./
            gfoclt_c ( "any",                            
                       "moon",    "ellipsoid",  "iau_moon", 
                       "sun",     "ellipsoid",  "iau_sun", 
                       "lt",      "earth",      step, 
                       &cnfine,   &result                 );

            if ( wncard_c(&result) == 0 )
            {
               printf ( "No occultation was found.\n" ); 
            }
            else
            {
               for ( i = 0;  i < wncard_c(&result); i++ )
               { 
                  /.
                  Fetch and display each occultation interval.
                  ./
                  wnfetd_c ( &result, i, &left, &right );

                  timout_c ( left,  TIMFMT, TIMLEN, begstr );
                  timout_c ( right, TIMFMT, TIMLEN, endstr );

                  printf ( "Interval %ld\n"
                           "   Start time: %s\n" 
                           "   Stop time:  %s\n",
                           i, begstr, endstr      );
               }
            }

            return ( 0 );
         }

 
      When this program was executed on a PC/Linux/gcc platform, the
      output was:
 
         Interval 0
            Start time: 2001 DEC 14 20:10:14.195952 (TDB)
            Stop time:  2001 DEC 14 21:35:50.317994 (TDB)

 
   2) Find occultations of Titan by Saturn or of Saturn by
      Titan as seen from the center of the Earth over the
      last four months of 2008. Model both target bodies as
      ellipsoids. Search for every type of occultation.

      Use light time corrections to model apparent positions of
      Saturn and Titan. Stellar aberration corrections are not
      specified because they don't affect occultation computations.

      We select a step size of 15 minutes, which means we
      ignore occultation events lasting less than 15 minutes,
      if any exist.

      Use the meta-kernel shown below to load the required SPICE
      kernels.


         KPL/MK

         File name: gfoclt_ex2.tm

         This meta-kernel is intended to support operation of SPICE
         example programs. The kernels shown here should not be
         assumed to contain adequate or correct versions of data
         required by SPICE-based user applications.

         In order for an application to use this meta-kernel, the
         kernels referenced here must be present in the user's
         current working directory.

         The names and contents of the kernels referenced
         by this meta-kernel are as follows:

            File name                     Contents
            ---------                     --------
            de421.bsp                     Planetary ephemeris
            sat288.bsp                    Satellite ephemeris for
                                          Saturn
            pck00008.tpc                  Planet orientation and
                                          radii
            naif0009.tls                  Leapseconds

         \begindata

            KERNELS_TO_LOAD = ( 'de421.bsp',
                                'sat288.bsp',
                                'pck00008.tpc',
                                'naif0009.tls'  )

         \begintext

         End of meta-kernel


     Example code begins here.
      
        #include <stdio.h>
        #include <string.h>
        #include "SpiceUsr.h"

        int main()
        {
           /.
           Local constants 
           ./
           #define TIMFMT          "YYYY MON DD HR:MN:SC.###### (TDB)::TDB"
           #define MAXWIN          200
           #define TIMLEN          41
           #define LNSIZE          81
           #define NTYPES          4

           /.
           Local variables 
           ./
           SPICEDOUBLE_CELL      ( cnfine, MAXWIN );
           SPICEDOUBLE_CELL      ( result, MAXWIN );

           SpiceChar             * back;
           SpiceChar             * bframe;
           SpiceChar             * front;
           SpiceChar             * fframe;
           SpiceChar               line   [ LNSIZE ];
           SpiceChar             * obsrvr;   

           SpiceChar             * occtyp [ NTYPES ] =
                                   {
                                      "FULL",
                                      "ANNULAR",
                                      "PARTIAL",
                                      "ANY"
                                   };

           SpiceChar             * templt [ NTYPES ] =
                                   {
                                      "Condition: # occultation of # by #",
                                      "Condition: # occultation of # by #",
                                      "Condition: # occultation of # by #",
                                      "Condition: # occultation of # by #"
                                   };

           SpiceChar               timstr [ TIMLEN ];
           SpiceChar               title  [ LNSIZE ];
           SpiceChar             * win0;
           SpiceChar             * win1;

           SpiceDouble             et0;
           SpiceDouble             et1;
           SpiceDouble             finish;
           SpiceDouble             start;
           SpiceDouble             step;

           SpiceInt                i;
           SpiceInt                j;
           SpiceInt                k;

           /.
           Load kernels. 
           ./
           furnsh_c ( "gfoclt_ex2.tm" );

           /.
           Obtain the TDB time bounds of the confinement
           window, which is a single interval in this case.
           ./
           win0 = "2008 SEP 01 00:00:00 TDB";
           win1 = "2009 JAN 01 00:00:00 TDB";

           str2et_c ( win0, &et0 );
           str2et_c ( win1, &et1 );

           /.
           Insert the time bounds into the confinement
           window.
           ./
           wninsd_c ( et0, et1, &cnfine );

           /.
           Select a 15-minute step. We'll ignore any occultations
           lasting less than 15 minutes. Units are TDB seconds.
           ./
           step = 900.0;

           /.
           The observation location is the Earth.
           ./
           obsrvr = "Earth";

           /.
           Loop over the occultation types.
           ./
           for ( i = 0;  i < NTYPES;  i++ )
           {
              /.
              For each type, do a search for both transits of
              Titan across Saturn and occultations of Titan by
              Saturn.
              ./
              for ( j = 0;  j < 2;  j++ )
              {
                 if ( j == 0 )
                 {
                    front  = "TITAN";
                    fframe = "IAU_TITAN";
                    back   = "SATURN";
                    bframe = "IAU_SATURN";
                 }
                 else
                 {
                    front  = "SATURN";
                    fframe = "IAU_SATURN";
                    back   = "TITAN";
                    bframe = "IAU_TITAN";
                 }

                 /.
                 Perform the search. The target body shapes
                 are modeled as ellipsoids.
                 ./
                 gfoclt_c ( occtyp[i],                            
                            front,    "ellipsoid",  fframe, 
                            back,     "ellipsoid",  bframe,  
                            "lt",     obsrvr,       step,   
                            &cnfine,  &result               );

                 /.
                 Display the results. 
                 ./
                 printf ( "\n" );

                 /.
                 Substitute the occultation type and target
                 body names into the title string:
                 ./
                 repmc_c ( templt[i], "#", occtyp[i], LNSIZE, title );
                 repmc_c ( title,     "#", back,      LNSIZE, title );
                 repmc_c ( title,     "#", front,     LNSIZE, title );

                 printf ( "%s\n", title );

                 if ( wncard_c(&result) == 0 )
                 {
                    printf ( " Result window is empty: "
                             "no occultation was found.\n" );
                 }
                 else
                 {
                    printf ( " Result window start, stop times:\n" );

                    for ( k = 0;  k < wncard_c(&result);  k++ )
                    { 
                       /.
                       Fetch the endpoints of the kth interval
                       of the result window.
                       ./
                       wnfetd_c ( &result, k, &start, &finish );

                       /.
                       Call strncpy with a length of 7 to include
                       a terminating null. 
                       ./
                       strncpy ( line, "  #  #", 7 );

                       timout_c ( start,  TIMFMT, TIMLEN, timstr );

                       repmc_c  ( line, "#", timstr, LNSIZE, line );

                       timout_c ( finish, TIMFMT, TIMLEN, timstr );

                       repmc_c  ( line, "#", timstr, LNSIZE, line );

                       printf ( "%s\n", line );
                    }
                 }
                 /.
                 We've finished displaying the results of the
                 current search.
                 ./
              }
              /.
              We've finished displaying the results of the
              searches using the current occultation type.
              ./
           }
           printf ( "\n" );

           return ( 0 );
        }

 
      When this program was executed on a PC/Linux/gcc platform, the
      output was:


         Condition: FULL occultation of SATURN by TITAN
          Result window is empty: no occultation was found.

         Condition: FULL occultation of TITAN by SATURN
          Result window start, stop times:
           2008 OCT 27 22:08:01.627053 (TDB)  2008 OCT 28 01:05:03.375236 (TDB)
           2008 NOV 12 21:21:59.252262 (TDB)  2008 NOV 13 02:06:05.053051 (TDB)
           2008 NOV 28 20:49:02.402832 (TDB)  2008 NOV 29 02:13:58.986344 (TDB)
           2008 DEC 14 20:05:09.246177 (TDB)  2008 DEC 15 01:44:53.523002 (TDB)
           2008 DEC 30 19:00:56.577073 (TDB)  2008 DEC 31 00:42:43.222909 (TDB)

         Condition: ANNULAR occultation of SATURN by TITAN
          Result window start, stop times:
           2008 OCT 19 21:29:20.599087 (TDB)  2008 OCT 19 22:53:34.518737 (TDB)
           2008 NOV 04 20:15:38.620368 (TDB)  2008 NOV 05 00:18:59.139978 (TDB)
           2008 NOV 20 19:38:59.647712 (TDB)  2008 NOV 21 00:35:26.725908 (TDB)
           2008 DEC 06 18:58:34.073268 (TDB)  2008 DEC 07 00:16:17.647040 (TDB)
           2008 DEC 22 18:02:46.288289 (TDB)  2008 DEC 22 23:26:52.712459 (TDB)

         Condition: ANNULAR occultation of TITAN by SATURN
          Result window is empty: no occultation was found.

         Condition: PARTIAL occultation of SATURN by TITAN
          Result window start, stop times:
           2008 OCT 19 20:44:30.326771 (TDB)  2008 OCT 19 21:29:20.599087 (TDB)
           2008 OCT 19 22:53:34.518737 (TDB)  2008 OCT 19 23:38:26.250580 (TDB)
           2008 NOV 04 19:54:40.339331 (TDB)  2008 NOV 04 20:15:38.620368 (TDB)
           2008 NOV 05 00:18:59.139978 (TDB)  2008 NOV 05 00:39:58.612935 (TDB)
           2008 NOV 20 19:21:46.689523 (TDB)  2008 NOV 20 19:38:59.647712 (TDB)
           2008 NOV 21 00:35:26.725908 (TDB)  2008 NOV 21 00:52:40.604703 (TDB)
           2008 DEC 06 18:42:36.100544 (TDB)  2008 DEC 06 18:58:34.073268 (TDB)
           2008 DEC 07 00:16:17.647040 (TDB)  2008 DEC 07 00:32:16.324244 (TDB)
           2008 DEC 22 17:47:10.776722 (TDB)  2008 DEC 22 18:02:46.288289 (TDB)
           2008 DEC 22 23:26:52.712459 (TDB)  2008 DEC 22 23:42:28.850542 (TDB)

         Condition: PARTIAL occultation of TITAN by SATURN
          Result window start, stop times:
           2008 OCT 27 21:37:16.970175 (TDB)  2008 OCT 27 22:08:01.627053 (TDB)
           2008 OCT 28 01:05:03.375236 (TDB)  2008 OCT 28 01:35:49.266506 (TDB)
           2008 NOV 12 21:01:47.105498 (TDB)  2008 NOV 12 21:21:59.252262 (TDB)
           2008 NOV 13 02:06:05.053051 (TDB)  2008 NOV 13 02:26:18.227357 (TDB)
           2008 NOV 28 20:31:28.522707 (TDB)  2008 NOV 28 20:49:02.402832 (TDB)
           2008 NOV 29 02:13:58.986344 (TDB)  2008 NOV 29 02:31:33.691598 (TDB)
           2008 DEC 14 19:48:27.094229 (TDB)  2008 DEC 14 20:05:09.246177 (TDB)
           2008 DEC 15 01:44:53.523002 (TDB)  2008 DEC 15 02:01:36.360243 (TDB)
           2008 DEC 30 18:44:23.485898 (TDB)  2008 DEC 30 19:00:56.577073 (TDB)
           2008 DEC 31 00:42:43.222909 (TDB)  2008 DEC 31 00:59:17.030568 (TDB)

         Condition: ANY occultation of SATURN by TITAN
          Result window start, stop times:
           2008 OCT 19 20:44:30.326771 (TDB)  2008 OCT 19 23:38:26.250580 (TDB)
           2008 NOV 04 19:54:40.339331 (TDB)  2008 NOV 05 00:39:58.612935 (TDB)
           2008 NOV 20 19:21:46.689523 (TDB)  2008 NOV 21 00:52:40.604703 (TDB)
           2008 DEC 06 18:42:36.100544 (TDB)  2008 DEC 07 00:32:16.324244 (TDB)
           2008 DEC 22 17:47:10.776722 (TDB)  2008 DEC 22 23:42:28.850542 (TDB)

         Condition: ANY occultation of TITAN by SATURN
          Result window start, stop times:
           2008 OCT 27 21:37:16.970175 (TDB)  2008 OCT 28 01:35:49.266506 (TDB)
           2008 NOV 12 21:01:47.105498 (TDB)  2008 NOV 13 02:26:18.227357 (TDB)
           2008 NOV 28 20:31:28.522707 (TDB)  2008 NOV 29 02:31:33.691598 (TDB)
           2008 DEC 14 19:48:27.094229 (TDB)  2008 DEC 15 02:01:36.360243 (TDB)
           2008 DEC 30 18:44:23.485898 (TDB)  2008 DEC 31 00:59:17.030568 (TDB)


-Restrictions
 
   The kernel files to be used by gfoclt_c must be loaded (normally via 
   the CSPICE routine furnsh_c) before gfoclt_c is called. 
 
-Literature_References
 
  None. 
 
-Author_and_Institution
 
  N. J. Bachman  (JPL) 
  L. S. Elson    (JPL) 
  E. D. Wright   (JPL) 
 
-Version
 
   -CSPICE Version 1.0.0, 07-APR-2009 (NJB) (LSE) (EDW)

-Index_Entries
 
   GF occultation search

-&
*/

{ /* Begin gfoclt_c */


   /*
   Local variables 
   */
   static const SpiceChar  * blankStr = " ";

   SpiceChar               * bFrameStr;
   SpiceChar               * fFrameStr;


   /*
   Participate in error tracing.
   */
   if ( return_c() )
   {
      return;
   }
   chkin_c ( "gfoclt_c" );


   /*
   Make sure cell data types are d.p. 
   */
   CELLTYPECHK2 ( CHK_STANDARD, "gfoclt_c", SPICE_DP, cnfine, result );

   /*
   Initialize the input cells if necessary. 
   */
   CELLINIT2 ( cnfine, result );

   /*
   The input frame names are special cases because we allow the caller
   to pass in empty strings. If either of these strings are empty,
   we pass a null-terminated string containing one blank character to
   the underlying f2c'd routine. 

   First make sure the frame name pointers are non-null.
   */
   CHKPTR ( CHK_STANDARD, "gfoclt_c", bframe );
   CHKPTR ( CHK_STANDARD, "gfoclt_c", fframe );

   /*
   Use the input frame strings if they're non-empty; otherwise
   use blank strings for the frame names.
   */
  
   if ( bframe[0] )
   {
      bFrameStr = (SpiceChar *) bframe;
   }
   else
   {
      bFrameStr = (SpiceChar *) blankStr;
   }

   if ( fframe[0] )
   {
      fFrameStr = (SpiceChar *) fframe;
   }
   else
   {
      fFrameStr = (SpiceChar *) blankStr;
   }


   /*
   Check the other input strings to make sure each pointer is non-null 
   and each string length is non-zero.
   */
   CHKFSTR ( CHK_STANDARD, "gfoclt_c", occtyp );
   CHKFSTR ( CHK_STANDARD, "gfoclt_c", front  );
   CHKFSTR ( CHK_STANDARD, "gfoclt_c", fshape );
   CHKFSTR ( CHK_STANDARD, "gfoclt_c", back   );
   CHKFSTR ( CHK_STANDARD, "gfoclt_c", bshape );
   CHKFSTR ( CHK_STANDARD, "gfoclt_c", abcorr );
   CHKFSTR ( CHK_STANDARD, "gfoclt_c", obsrvr );


   /*
   Let the f2c'd routine do the work. 
   */
   gfoclt_ ( (char         *) occtyp,
             (char         *) front,
             (char         *) fshape,
             (char         *) fFrameStr,
             (char         *) back,
             (char         *) bshape,
             (char         *) bFrameStr,
             (char         *) abcorr,
             (char         *) obsrvr,
             (doublereal   *) &step,
             (doublereal   *) cnfine->base,
             (doublereal   *) result->base,
             (ftnlen        ) strlen(occtyp),
             (ftnlen        ) strlen(front),
             (ftnlen        ) strlen(fshape),
             (ftnlen        ) strlen(fframe),
             (ftnlen        ) strlen(back),
             (ftnlen        ) strlen(bshape),
             (ftnlen        ) strlen(bframe),
             (ftnlen        ) strlen(abcorr),
             (ftnlen        ) strlen(obsrvr)  );

   /*
   Sync the output result cell. 
   */
   if ( !failed_c() )
   {
      zzsynccl_c ( F2C, result );
   }


   chkout_c ( "gfoclt_c" );

} /* End gfoclt_c */
Ejemplo n.º 29
0
   void pckcov_c ( ConstSpiceChar   * pck,
                   SpiceInt           idcode,
                   SpiceCell        * cover   ) 
/*

-Brief_I/O
 
   Variable  I/O  Description 
   --------  ---  -------------------------------------------------- 
   pck        I   Name of PCK file. 
   idcode     I   Class ID code of PCK reference frame. 
   cover     I/O  Window giving coverage in `pck' for `idcode'. 
 
-Detailed_Input
 
   pck            is the name of a binary PCK file.
 
   idcode         is the integer frame class ID code of a PCK reference
                  frame for which data are expected to exist in the
                  specified PCK file.
 
   cover          is an initialized CSPICE window data structure.
                  `cover' optionally may contain coverage data on
                  input; on output, the data already present in `cover'
                  will be combined with coverage found for the
                  reference frame designated by `idcode' in the file
                  `pck'.
 
                  If `cover' contains no data on input, its size and
                  cardinality still must be initialized.
                   
-Detailed_Output
 
   cover          is a CSPICE window data structure which represents
                  the merged coverage for the reference frame having
                  frame class ID `idcode'. This is the set of time
                  intervals for which data for `idcode' are present in
                  the file `pck', merged with the set of time intervals
                  present in `cover' on input.  The merged coverage is
                  represented as the union of one or more disjoint time
                  intervals. The window `cover' contains the pairs of
                  endpoints of these intervals.
 
                  The interval endpoints contained in `cover' are 
                  ephemeris times, expressed as seconds past J2000 
                  TDB. 
 
                  See the Examples section below for a complete 
                  example program showing how to retrieve the 
                  endpoints from `cover'. 
                                     
-Parameters
 
   None. 
 
-Exceptions
 
   1)  If the input file has transfer format, the error  
       SPICE(INVALIDFORMAT) is signaled. 
 
   2)  If the input file is not a transfer file but has architecture 
       other than DAF, the error SPICE(BADARCHTYPE) is signaled. 
 
   3)  If the input file is a binary DAF file of type other than 
       PCK, the error SPICE(BADFILETYPE) is signaled. 
 
   4)  If the PCK file cannot be opened or read, the error will 
       be diagnosed by routines called by this routine. The output 
       window will not be modified. 
 
   5)  If the size of the output window argument COVER is 
       insufficient to contain the actual number of intervals in the 
       coverage window for IDCODE, the error will be diagnosed by 
       routines called by this routine.   
 
   6)  The error SPICE(EMPTYSTRING) is signaled if the input
       string `pck' does not contain at least one character, since the
       input string cannot be converted to a Fortran-style string in
       this case.
      
   7)  The error SPICE(NULLPOINTER) is signaled if the input string
       pointer `pck' is null.

-Files
 
   This routine reads a PCK file. 
 
-Particulars
 
   This routine provides an API via which applications can determine 
   the coverage a specified PCK file provides for a specified 
   PCK class reference frame. 
 
-Examples
 
   1)  This example demonstrates combined usage of pckcov_c and the 
       related PCK utility pckfrm_c. 
 
       Display the coverage for each object in a specified PCK file. 
       Find the set of objects in the file; for each object, find 
       and display the coverage. 
 

          #include <stdio.h>
          #include "SpiceUsr.h"

          int main()
          {
             /.
             Local parameters
             ./
             #define  FILSIZ         256
             #define  MAXIV          1000
             #define  WINSIZ         ( 2 * MAXIV )
             #define  TIMLEN         51
             #define  MAXOBJ         1000

             /.
             Local variables
             ./
             SPICEDOUBLE_CELL        ( cover, WINSIZ );
             SPICEINT_CELL           ( ids,   MAXOBJ );

             SpiceChar               lsk     [ FILSIZ ];
             SpiceChar               pck     [ FILSIZ ];
             SpiceChar               timstr  [ TIMLEN ];

             SpiceDouble             b;
             SpiceDouble             e;

             SpiceInt                i;
             SpiceInt                j;
             SpiceInt                niv;
             SpiceInt                obj;


             /.
             Load a leapseconds kernel for output time conversion.
             PCKCOV itself does not require a leapseconds kernel.
             ./
             prompt_c ( "Name of leapseconds kernel > ", FILSIZ, lsk );
             furnsh_c ( lsk );

             /.
             Get name of PCK file.
             ./
             prompt_c ( "Name of PCK file           > ", FILSIZ, pck    );

             /.
             Find the set of frames in the PCK file. 
             ./
             pckfrm_c ( pck, &ids );

             /.
             We want to display the coverage for each frame. Loop over
             the contents of the ID code set, find the coverage for
             each item in the set, and display the coverage.
             ./
             for ( i = 0;  i < card_c( &ids );  i++  )
             {
                /.
                Find the coverage window for the current frame. 
                Empty the coverage window each time so we don't
                include data for the previous frame.
                ./
                obj  =  SPICE_CELL_ELEM_I( &ids, i );

                scard_c  ( 0,        &cover );
                pckcov_c ( pck, obj, &cover );

                /.
                Get the number of intervals in the coverage window.
                ./
                niv = wncard_c ( &cover );

                /.
                Display a simple banner.
                ./
                printf ( "%s\n", "========================================" );

                printf ( "Coverage for frame %ld\n", obj );

                /.
                Convert the coverage interval start and stop times to TDB
                calendar strings.
                ./
                for ( j = 0;  j < niv;  j++  )
                {
                   /.
                   Get the endpoints of the jth interval.
                   ./
                   wnfetd_c ( &cover, j, &b, &e );

                   /.
                   Convert the endpoints to TDB calendar
                   format time strings and display them.
                   ./
                   timout_c ( b, 
                              "YYYY MON DD HR:MN:SC.### (TDB) ::TDB",  
                              TIMLEN,
                              timstr                                  );

                   printf ( "\n"
                            "Interval:  %ld\n"
                            "Start:     %s\n",
                            j,
                            timstr            );

                   timout_c ( e, 
                              "YYYY MON DD HR:MN:SC.### (TDB) ::TDB",  
                              TIMLEN,
                              timstr                                  );
                   printf ( "Stop:      %s\n", timstr );

                }

             }
             return ( 0 );
          } 
 

   2) Find the coverage for the frame designated by `idcode' 
      provided by the set of PCK files loaded via a metakernel. 
      (The metakernel must also specify a leapseconds kernel.) 
        
         #include <stdio.h>
         #include "SpiceUsr.h"

         int main()
         {

            /.
            Local parameters
            ./
            #define  FILSIZ         256
            #define  LNSIZE         81 
            #define  MAXCOV         100000
            #define  WINSIZ         ( 2 * MAXCOV )
            #define  TIMLEN         51

            /.
            Local variables
            ./
            SPICEDOUBLE_CELL        ( cover, WINSIZ );

            SpiceBoolean            found;

            SpiceChar               file    [ FILSIZ ];
            SpiceChar               idch    [ LNSIZE ];
            SpiceChar               meta    [ FILSIZ ];
            SpiceChar               source  [ FILSIZ ];
            SpiceChar               timstr  [ TIMLEN ];
            SpiceChar               type    [ LNSIZE ];

            SpiceDouble             b;
            SpiceDouble             e;

            SpiceInt                count;
            SpiceInt                handle;
            SpiceInt                i;
            SpiceInt                idcode;
            SpiceInt                niv;


            /.
            Prompt for the metakernel name; load the metakernel.
            The metakernel lists the PCK files whose coverage
            for `idcode' we'd like to determine.  The metakernel
            must also specify a leapseconds kernel.
            ./
            prompt_c ( "Name of metakernel > ", FILSIZ, meta );
            furnsh_c ( meta );

            /.
            Get the ID code of interest. 
            ./
            prompt_c ( "Enter ID code      > ", LNSIZE, idch );
            prsint_c ( idch,  &idcode );

            /.
            Find out how many kernels are loaded.  Loop over the
            kernels:  for each loaded PCK file, add its coverage
            for `idcode', if any, to the coverage window.
            ./
            ktotal_c ( "PCK", &count );

            for ( i = 0;  i < count;  i++  )
            {
               kdata_c  ( i,     "PCK",   FILSIZ,  LNSIZE,   FILSIZ, 
                          file,  type,    source,  &handle,  &found );

               pckcov_c ( file,  idcode,  &cover );
            }

            /.
            Display results. 

            Get the number of intervals in the coverage window.
            ./
            niv = wncard_c ( &cover );

            /.
            Display a simple banner.
            ./
            printf ( "\nCoverage for frame %ld\n", idcode );

            /.
            Convert the coverage interval start and stop times to TDB
            calendar strings.
            ./
            for ( i = 0;  i < niv;  i++  )
            {
               /.
               Get the endpoints of the ith interval.
               ./
               wnfetd_c ( &cover, i, &b, &e );

               /.
               Convert the endpoints to TDB calendar
               format time strings and display them.
               ./
               timout_c ( b, 
                          "YYYY MON DD HR:MN:SC.### (TDB) ::TDB",  
                          TIMLEN,
                          timstr                                  );

               printf ( "\n"
                        "Interval:  %ld\n"
                        "Start:     %s\n",
                        i,
                        timstr            );

               timout_c ( e, 
                          "YYYY MON DD HR:MN:SC.### (TDB) ::TDB",  
                          TIMLEN,
                          timstr                                  );
               printf ( "Stop:      %s\n", timstr );

            }
            return ( 0 );
         }


 
-Restrictions
 
   1) If an error occurs while this routine is updating the window 
      `cover', the window may be corrupted. 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman   (JPL) 
 
-Version
 
   -CSPICE Version 1.0.1, 01-JUL-2014 (NJB)

       Updated index entries.

   -CSPICE Version 1.0.0, 30-NOV-2007 (NJB)

-Index_Entries
 
   get coverage window for binary pck reference frame
   get coverage start and stop time for binary pck frame 

-&
*/

{ /* Begin pckcov_c */


   /*
   Participate in error tracing.
   */
   if ( return_c() )
   {
      return; 
   }
   chkin_c ( "pckcov_c" );


   /*
   Check the input string `pck' to make sure the pointer is non-null 
   and the string length is non-zero.
   */
   CHKFSTR ( CHK_STANDARD, "pckcov_c", pck );
   
   /*
   Make sure cell data type is d.p. 
   */
   CELLTYPECHK ( CHK_STANDARD, "pckcov_c", SPICE_DP, cover );

   /*
   Initialize the cell if necessary. 
   */
   CELLINIT ( cover );   

   /*
   Call the f2c'd Fortran routine.
   */
   pckcov_ ( ( char       * ) pck,
             ( integer    * ) &idcode,
             ( doublereal * ) (cover->base),
             ( ftnlen       ) strlen(pck)   );

   /*
   Sync the output cell. 
   */
   if ( !failed_c() )
   {
      zzsynccl_c ( F2C, cover );
   }


   chkout_c ( "pckcov_c" );

} /* End pckcov_c */
Ejemplo n.º 30
0
	//function to load new data into the body
	void body::load_body_data(const int& ibody_code, const string& iname, const string& ishortname, const int& ispice_ID, const double& imininum_altitude, const double& imass, const double& iradius, const double& iepoch, vector<double>& ireference_angles, vector<double>& iclassical_orbit_elements, const double& iuniverse_mu, const int& icentral_body_SPICE_ID, const string& icentral_body_name, const double& icentral_body_radius, missionoptions* options)
	{
		//copy information from the inputs into the body
		this->name = iname;
		this->short_name = ishortname;
		this->universe_mu = iuniverse_mu;
		this->body_code = ibody_code;
		this->central_body_spice_ID = icentral_body_SPICE_ID;
		this->central_body_name = icentral_body_name;
		this->central_body_radius = icentral_body_radius;

		this->spice_ID = ispice_ID;
		this->minimum_safe_flyby_altitude = imininum_altitude;
		this->mass = imass;
		this->radius = iradius;
		this->reference_epoch = iepoch;
		this->SMA = iclassical_orbit_elements[0];
		this->ECC = iclassical_orbit_elements[1];
		this->INC = iclassical_orbit_elements[2] * EMTG::math::PI / 180.0;
		this->RAAN = iclassical_orbit_elements[3] * EMTG::math::PI / 180.0;
		this->AOP = iclassical_orbit_elements[4] * EMTG::math::PI / 180.0;
		this->MA = iclassical_orbit_elements[5] * EMTG::math::PI / 180.0;
		


		//compute additional values
		mu = options->G * mass;
		if (ECC < 0.2)
			r_SOI = SMA * pow(mu / universe_mu, 0.4);
		else
			r_SOI = SMA * (1 - ECC) * pow(mu / (3.0 * universe_mu), 0.333333333333333333333333);

		//determine which ephemeris to draw from
		if (options->ephemeris_source == 0)
		{
			body_ephemeris_source = 0; //use static ephemeris
			ephemeris_start_date = -0;
			ephemeris_end_date = 1e+10;
		}
		else if (options->ephemeris_source == 1)
		{
			//first, check to see if the body exists in the currently loaded SPICE kernels
			double temp_state[6];
			double LT_dump;
			spkez_c (spice_ID, reference_epoch - (51544.5 * 86400.0), "J2000", "NONE", central_body_spice_ID, temp_state, &LT_dump);
			if (failed_c())
				reset_c();


			if (fabs(temp_state[0]) > 1.0e-6 && fabs(temp_state[0]) < 1.0e+50)
			{
				body_ephemeris_source = 1; //body can be located using SPICE
			}
			else
			{
				cout << "Warning, body " << name << " does not have a SPICE ephemeris file." << endl;
				body_ephemeris_source = 0; //use static ephemeris
				ephemeris_start_date = 0;
				ephemeris_end_date = 1e+10;
			}
		}

		J2000_body_equatorial_frame.initialize(ireference_angles[0], ireference_angles[1], ireference_angles[2], ireference_angles[3], ireference_angles[4], ireference_angles[5]);
	}