Пример #1
0
   void psv2pl_c ( ConstSpiceDouble    point[3],
                   ConstSpiceDouble    span1[3],
                   ConstSpiceDouble    span2[3],
                   SpicePlane        * plane    ) 
/*

-Brief_I/O
 
   Variable  I/O  Description 
   --------  ---  -------------------------------------------------- 
   point, 
   span1, 
   span2      I   A point and two spanning vectors defining a plane. 
   plane      O   A CSPICE plane representing the plane. 
 
-Detailed_Input
 
   point, 
   span1, 
   span2          are, respectively, a point and two spanning vectors 
                  that define a geometric plane in three-dimensional 
                  space. The plane is the set of vectors 
 
                     point   +   s * span1   +   t * span2 
 
                  where s and t are real numbers.  The spanning 
                  vectors span1 and span2 must be linearly 
                  independent, but they need not be orthogonal or 
                  unitized. 
 
-Detailed_Output
 
   plane          is a CSPICE plane that represents the geometric 
                  plane defined by point, span1, and span2. 
 
-Parameters
 
   None. 
 
-Exceptions
 
   1)  If span1 and span2 are linearly dependent, then the vectors 
       point, span1, and span2 do not define a plane.  The error 
       SPICE(DEGENERATECASE) is signaled. 
 
-Files
 
   None. 
 
-Particulars
 
   CSPICE geometry routines that deal with planes use the `plane' 
   data type to represent input and output planes.  This data type 
   makes the subroutine interfaces simpler and more uniform. 
 
   The CSPICE routines that produce CSPICE planes from data that 
   define a plane are: 
 
      nvc2pl_c ( Normal vector and constant to plane ) 
      nvp2pl_c ( Normal vector and point to plane    ) 
      psv2pl_c ( Point and spanning vectors to plane ) 
 
   The CSPICE routines that convert CSPICE planes to data that 
   define a plane are: 
 
      pl2nvc_c ( Plane to normal vector and constant ) 
      pl2nvp_c ( Plane to normal vector and point    ) 
      pl2psv_c ( Plane to point and spanning vectors ) 
 
   Any of these last three routines may be used to convert this 
   routine's output, plane, to another representation of a 
   geometric plane. 
 
-Examples
 
   1)  Project a vector v orthogonally onto a plane defined by 
       point, span1, and span2.  proj is the projection we want; it 
       is the closest vector in the plane to v. 
 
          psv2pl_c ( point,  span1,   span2,  &plane ); 
          vprjp_c  ( v,      &plane,  proj           );
 
 
   2)  Find the plane determined by a spacecraft's position vector 
       relative to a central body and the spacecraft's velocity 
       vector.  We assume that all vectors are given in the same 
       coordinate system. 
 
          /.
          pos is the spacecraft's position, relative to 
          the central body.  vel is the spacecraft's velocity 
          vector.  pos is a point (vector, if you like) in 
          the orbit plane, and it is also one of the spanning 
          vectors of the plane. 
          ./
          psv2pl_c ( pos, pos, vel, &plane );
           
 
-Restrictions
 
   None. 
 
-Literature_References
 
   [1] `Calculus and Analytic Geometry', Thomas and Finney. 
 
-Author_and_Institution
 
   N.J. Bachman   (JPL) 
 
-Version
 
   -CSPICE Version 1.0.0, 05-MAR-1999 (NJB)

-Index_Entries
 
   point and spanning vectors to plane 
 
-&
*/

{ /* Begin psv2pl_c */



   /*
   This routine checks in only if an error is discovered.
   */

   if ( return_c () ) 
   {
      return;
   }

   /*
   Find the unitized cross product of SPAN1 and SPAN2; this is our
   unit normal vector, or possibly its inverse.
   */
   ucrss_c (  span1,  span2,  plane->normal  );

   if (  vzero_c ( plane->normal )  )
   {
      chkin_c  ( "psv2pl_c"                       );
      setmsg_c ( "Spanning vectors are parallel." );
      sigerr_c ( "SPICE(DEGENERATECASE)"          );
      chkout_c ( "psv2pl_c"                       );
      return;
   }
 
 
   /*
   Find the plane constant corresponding to the unit normal
   vector we've found.
   */
   plane->constant  =  vdot_c ( plane->normal, point );
 
 
   /*
   The constant should be the distance of the plane from the
   origin.  If the constant is negative, negate both it and the
   normal vector.
   */
      
   if ( plane->constant  <  0. ) 
   {
      plane->constant  =   - (plane->constant);
      
      vminus_c ( plane->normal, plane->normal );
   }


} /* End psv2pl_c */
Пример #2
0
   void reordl_c ( ConstSpiceInt   * iorder,
                   SpiceInt          ndim,      
                   SpiceBoolean    * array ) 

/*

-Brief_I/O
 
   VARIABLE  I/O  DESCRIPTION 
   --------  ---  -------------------------------------------------- 
   iorder     I   Order vector to be used to re-order array. 
   ndim       I   Dimension of array. 
   array     I/O  Array to be re-ordered. 
 
-Detailed_Input
 
   iorder      is the order vector to be used to re-order the input 
               array. The first element of iorder is the index of 
               the first item of the re-ordered array, and so on. 

               Note that the order imposed by reordl_c is not the 
               same order that would be imposed by a sorting 
               routine. In general, the order vector will have 
               been created (by one of the order routines) for 
               a related array, as illustrated in the example below. 

               The elements of iorder range from zero to ndim-1.

   ndim        is the number of elements in the input array. 

   array       on input, is an array containing some number of 
               elements in unspecified order. 

-Detailed_Output
 
   array       on output, is the same array, with the elements 
               in re-ordered as specified by iorder. 
 
-Parameters
 
   None. 
 
-Exceptions
 
   1) If memory cannot be allocated to create a Fortran-style version of
      the input order vector, the error SPICE(MALLOCFAILED) is signaled.
 
   2) If memory cannot be allocated to create a type "logical" copy of the 
      the input SpiceBoolean array, the error SPICE(MALLOCFAILED) is 
      signaled.
 
   3) If ndim < 2, this routine executes a no-op.  This case is 
      not an error.

-Files
 
   None. 
 
-Particulars
 
   reordl_c uses a cyclical algorithm to re-order the elements of 
   the array in place. After re-ordering, element iorder[0] of 
   the input array is the first element of the output array, 
   element iorder[1] is the input array is the second element of 
   the output array, and so on. 

   The order vector used by reordl_c is typically created for 
   a related array by one of the order*_c routines, as shown in 
   the example below. 
 
-Examples

   In the following example, the order*_c and reord*_c routines are 
   used to sort four related arrays (containing the names, 
   masses, integer ID codes, and visual magnitudes for a group 
   of satellites). This is representative of the typical use of 
   these routines. 

      #include "SpiceUsr.h"
          .
          .
          .
      /.
      Sort the object arrays by name. 
      ./ 

      orderc_c ( namlen, names, n,  iorder ); 
ordvec
      reordc_c ( iorder, n, namlen, names  );
      reordd_c ( iorder, n,         masses ); 
      reordi_c ( iorder, n,         codes  ); 
      reordd_c ( iorder, n,         vmags  );
 
-Restrictions
 
   None. 
  
-Author_and_Institution
 
   N.J. Bachman    (JPL)
   W.L. Taber      (JPL) 
   I.M. Underwood  (JPL) 
 
-Literature_References
 
   None. 
 
-Version
 
   -CSPICE Version 1.0.0, 10-JUL-2002 (NJB) (WLT) (IMU)

-Index_Entries
 
   reorder a logical array 
 
-&
*/

{ /* Begin reordl_c */

   /*
   Local variables 
   */
   logical               * lArray;

   SpiceInt                aSize;
   SpiceInt                i ;
   SpiceInt              * ordvec;
   SpiceInt                vSize;



   /*
   If the input array doesn't have at least two elements, return
   immediately. 
   */
   if ( ndim < 2 )
   {
      return;
   }


   /*
   Get a local copy of the input order vector; map the vector's contents
   to the range 1:ndim. 
   */
   vSize  = ndim * sizeof(SpiceInt);

   ordvec = (SpiceInt *) malloc( vSize );

   if ( ordvec == 0 )
   {
      chkin_c  ( "reordl_c"                                ); 
      setmsg_c ( "Failure on malloc call to create array "
                 "for Fortran-style order vector.  Tried "
                 "to allocate # bytes."                    );
      errint_c ( "#",  vSize                               );
      sigerr_c ( "SPICE(MALLOCFAILED)"                     );
      chkout_c ( "reordl_c"                                );
      return;
   }

   for ( i = 0;  i < ndim;  i++ )
   {
      ordvec[i] = iorder[i] + 1;
   }

   /*
   Get a local copy of the input logical array; use type logical
   to ensure compatibility with code translated by f2c.
   */
   aSize  = ndim * sizeof(logical);

   lArray = (logical *) malloc( aSize );

   if ( lArray == 0 )
   {
      free ( ordvec );

      chkin_c  ( "reordl_c"                                ); 
      setmsg_c ( "Failure on malloc call to create array "
                 "for Fortran-style order vector.  Tried "
                 "to allocate # bytes."                    );
      errint_c ( "#",  aSize                               );
      sigerr_c ( "SPICE(MALLOCFAILED)"                     );
      chkout_c ( "reordl_c"                                );
      return;
   }

   for ( i = 0;  i < ndim;  i++ )
   {
      lArray[i] = array[i];
   }


   reordl_ ( ( integer * ) ordvec,
             ( integer * ) &ndim,
             ( logical * ) lArray );

   /*
   Write the re-ordered result to the output array.
   */
   for ( i = 0;  i < ndim;  i++ )
   {
      array[i] = (SpiceBoolean) lArray[i];
   }


   free ( ordvec );
   free ( lArray );


} /* End reordl_c */
Пример #3
0
   void insrtc_c ( ConstSpiceChar  * item,
                   SpiceCell       * set   )

/*

-Brief_I/O
 
   VARIABLE  I/O  DESCRIPTION 
   --------  ---  -------------------------------------------------- 
   item       I   Item to be inserted. 
   set       I/O  Insertion set. 
 
-Detailed_Input
 
   item        is an item which is to be inserted into the specified
               set. item may or may not already be an element of the
               set.  Trailing blanks in item are not significant.


   set         is a CSPICE set.  set must be declared as a character
               SpiceCell. 

               On input, set  may or may not contain the input item 
               as an element. 
 
-Detailed_Output

   set         on output contains the union of the input set and 
               the singleton set containing the input item.
 
-Parameters
 
   None. 
 
-Exceptions
 
   1) If the input set argument is a SpiceCell of type other than
      character, the error SPICE(TYPEMISMATCH) is signaled.

   2) If the insertion of the element into the set causes an excess 
      of elements, the error SPICE(SETEXCESS) is signaled. 
 
   3) If the input set argument does not qualify as a CSPICE set, 
      the error SPICE(NOTASET) will be signaled.  CSPICE sets have
      their data elements sorted in increasing order and contain
      no duplicate data elements.

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

-Files
 
   None. 
 
-Particulars
 
   None. 
 
-Examples
 
   1) In the following example, the element "PLUTO" is removed from 
      the character set planets and inserted into the character set 
      asteroids. 

         #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 );
                .
                .
                .
         removc_c ( "PLUTO", &planets   );
         insrtc_c ( "PLUTO", &asteroids ); 


      If "PLUTO" is not an element of planets, then the contents of 
      planets are not changed. Similarly, if "PLUTO" is already an 
      element of asteroids, the contents of asteroids remain unchanged. 

      Because inserting an element into a set can increase the 
      cardinality of the set, an error may occur in the insertion 
      routines. 
 
-Restrictions
 
   1)  String comparisons performed by this routine are Fortran-style:
       trailing blanks in the input set or key value 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 2.1.0, 07-MAR-2009 (NJB)

       This file now includes the header file f2cMang.h.
       This header supports name mangling of f2c library
       functions.

   -CSPICE Version 2.0.0, 01-NOV-2005 (NJB)
         
       Bug fix:  when the item to be inserted would, after
       truncation to the set's string length, match an item
       already in the set, no insertion is performed.  Previously
       the truncated string was inserted, corrupting the set.

       Long error message was updated to include size of
       set into which insertion was attempted.
         
   -CSPICE Version 1.0.0, 21-AUG-2002 (NJB) (CAC) (WLT) (IMU)

-Index_Entries
 
   insert an item into a character set 
 
-&
*/
{
   /*
   f2c library utility prototypes 
   */
   extern integer   s_cmp  (char *a, char *b, ftnlen la, ftnlen lb ); 


   /*
   Local macros 
   */
   #define ARRAY( i )    (  (SpiceChar *)(set->data) + (i)*(set->length)  )


   /*
   local variables
   */
   SpiceBoolean            inSet;

   SpiceChar             * cdata;

   SpiceInt                i;
   SpiceInt                loc;
   SpiceInt                slen;



   /*
   Use discovery check-in. 

   Check the input string pointer to make sure it's not null.
   */
   CHKPTR ( CHK_DISCOVER, "insrtc_c", item );


   /*
   Make sure we're working with a character cell. 
   */
   CELLTYPECHK ( CHK_DISCOVER, "insrtc_c", SPICE_CHR, set );


   /*
   Make sure the input cell is a set.
   */
   CELLISSETCHK ( CHK_DISCOVER, "insrtc_c", set );


   /*
   Initialize the set if it's not already initialized.
   */
   CELLINIT ( set );


   /*
   Let slen be the effective string length of the input item.
   Characters beyond the string length of the set are ignored.
   */
   slen = mini_c ( 2, set->length, strlen(item) );


   /*
   Is the item already in the set? If not, it needs to be inserted.
   */
   cdata =  (SpiceChar *) (set->data);

   /*
   The following call will give the location of the last element
   less than or equal to the item to be inserted.  If the item
   differs from an element of the set only in characters that would
   be truncated, no insertion will occur.  Even in this case, the
   insertion point `loc' returned by lstlec_c will be correct.
   */
   loc   =  lstlec_c ( item,  set->card,  set->length,  cdata );

   inSet =     (  loc  >  -1  ) 

            && (  s_cmp( (SpiceChar *)item,  ARRAY(loc), 
                          slen,              strlen(ARRAY(loc)) ) == 0  );
 
   if ( inSet )
   {
      return;
   }

   
   /*
   It's an error if the set has no room left. 
   */
   if ( set->card == set->size )
   {
      chkin_c  ( "insrtc_c"                                       );
      setmsg_c ( "An element could not be inserted into the set "
                 "due to lack of space; set size is #."           );
      errint_c ( "#", set->size                                   );
      sigerr_c ( "SPICE(SETEXCESS)"                               );
      chkout_c ( "insrtc_c"                                       );
      return;
   }


   /*
   Make room by moving the items that come after index loc in the set. 
   Insert the item after index loc.
   */
   for (  i = (set->card);   i > (loc+1);   i--  )
   {
      SPICE_CELL_SET_C( ARRAY(i-1), i, set );
   }

   /*
   This insertion macro will truncate the item to be inserted, if 
   necessary.  The input item will be null-terminated.
   */
   SPICE_CELL_SET_C( item, loc+1, set );


   /*
   Increment the set's cardinality.
   */
   (set->card) ++;

}
Пример #4
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 */
Пример #5
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 */
Пример #6
0
GetData::GetData(string dskfilepath, string currentPath){
	
	SpiceInt handle;
	SpiceDLADescr dladsc;
	//int i,j,k,l,norme1,norme2,p,q;
	//int flag = 0;
	//int cont;
	FILE *f;
	printf("getdata\n");
	string fname = "/Desktop/commonF_aft.dat";
	fname = currentPath + fname;
	dasopr_c(dskfilepath.c_str(), &handle);
	dlabfs_c(handle,&dladsc,&found);
	//f = fopen("/Users/m5151134/Desktop/commonF_aft.dat", "w");
	f = fopen(fname.c_str(), "w");
	if(!found){
		
		setmsg_c ( "No segments found in DSK file #." );
		sigerr_c ( "SPICE(NODATA)"                    );
			
		
	}
	
	//Get Number of Plate
	dski02_c ( handle, &dladsc, SPICE_DSK_KWNP, 
			  0,      1,       &n,             &np );
	
	pd = new int*[np];
	pd[0] = new int[np * 3];
	for (i = 1; i < np; i++) pd[i] = pd[0] + i * 3;
	
	//Get Number of Vertices
	dski02_c ( handle, &dladsc, SPICE_DSK_KWNV, 
			  0,      1,       &n,             &nv );
	
	vd = new double*[nv];
	vd[0] = new double[nv*3];
	for (i = 1; i < nv; i++) vd[i] = vd[0] + i * 3;
	
	readPlateData(handle,dladsc);
	readVerticesData(handle,dladsc);
	
	
	dascls_c ( handle );

	/*
for (i = 0 ; i < nv ; i++) {
	printf("%d %d %d %d %d\n",i,nv,pd[i][0],pd[i][1],pd[i][2]);
}	
	*/
	int fppp=0,fppm=0,fpmp=0,fmpp=0,fpmm=0,fmpm=0,fmmp=0,fmmm=0;
	for ( i = 0 ; i < np ; i++) {
		for ( int j = 0 ; j < 3 ; j++) {
//printf("check:%d %d %d %d %d\n",i,j,nv,np,pd[i][j]);
			double x = vd[pd[i][j]-1][0];
			double y = vd[pd[i][j]-1][1];
			double z = vd[pd[i][j]-1][2];
			
			//+x+y+z
			if (x >= 0 && y >= 0 && z>= 0 && fppp == 0) {
				ppp.push_back(i+1);
				fppp = 1;
			}
			//+x+y-z
			if (x >= 0 && y >= 0 && z <= 0 && fppm == 0) {
				ppm.push_back(i+1);
				fppm = 1;
			}
			//+x-y+z
			if (x >= 0 && y <= 0 && z >= 0 && fpmp == 0) {
				pmp.push_back(i+1);
				fpmp = 1;
			}
			//-x+y+z
			if (x <= 0 && y >= 0 && z >= 0 && fmpp == 0) {
				mpp.push_back(i+1);
				fmpp = 1;
			}
			//+x-y-z
			if (x >= 0 && y <= 0 && z <= 0 && fpmm == 0) {
				pmm.push_back(i+1);
				fpmm = 1;
			}
			//-x+y-z
			if (x <= 0 && y >= 0 && z <= 0 && fmpm == 0) {
				mpm.push_back(i+1);
				fmpm = 1;
			}
			//-x-y+z
			if (x <= 0 && y <= 0 && z >= 0 && fmmp == 0) {
				mmp.push_back(i+1);
				fmmp = 1;
			}
			//-x-y-z
			if (x <= 0 && y <= 0 && z <= 0 && fmmm == 0) {
				mmm.push_back(i+1);
				fmmm = 1;
			}
		}
		fppp=0;
		fppm=0;
		fpmp=0;
		fmpp=0;
		fpmm=0;
		fmpm=0;
		fmmp=0;
		fmmm=0;
	}
	
	
		
	
	commonF = new int*[np];
	commonF[0] = new int[np * 3];
	for (i = 1; i < np; i++) commonF[i] = commonF[0] + i * 3;
	
	/*
	for( i = 0 ; i < np ; i++){
		printf("nv:%d np:%d pd0:%d p1:%d p2:%d\n",nv,np,pd[i][0],pd[i][1],pd[i][2]);
	}
	*/
	
	
	
	map<int,set<int> > dict;
	for(int i = 0; i < np; ++i){
		for(int j = 0; j < 3; ++j){
			dict[pd[i][j]].insert(i);
		}
	}
	
	int *conts = new int[np];
	for(int i = 0; i < np; ++i){
		conts[i] = 0;
	}
	for(int i = 0; i < np; ++i){
		set<int> ids;
		for(int j = 0; j < 3; ++j){
			for(set<int>::iterator it = dict[pd[i][j]].begin(); it != dict[pd[i][j]].end(); ++it){
				ids.insert( *it );
			}
		}
		int cnt = 0;
		int id_array[ids.size()];
		for(set<int>::iterator it = ids.begin(); it != ids.end(); ++it){
			id_array[cnt++] = *it;
		}
		for(int j = 0; j < ids.size(); ++j){
            int fid = 0;
            fid = id_array[j];
			for(int k = 0; k < ids.size(); ++k){
                int sid = 0;
                sid = id_array[k];
				if( fid != sid ){
					
					for(int ii = 0; ii < 3; ++ii){
						int norme1 = pd[fid][ii];
						int norme2 = pd[fid][(ii+1)%3];
						
						for(int jj = 0; jj < 3; ++jj){
							int normf1 = pd[sid][jj];
							int normf2 = pd[sid][(jj+1)%3];
							
							if( (norme1 == normf1 && norme2 == normf2) || (norme1 == normf2 && norme2 == normf1) ){
								if( conts[fid] >= 3 ) continue;
								bool ng = false;
								for(int kk = 0; kk < conts[fid]; ++kk){
									if( commonF[fid][kk] == sid+1 ){
										ng = true;
									}
								}
								if( !ng ){
									commonF[fid][conts[fid]++] = sid+1;
								}
							}
						}
					}
				}
			}
		}			
	}
	 
	//printf("getdata: %d",commonF[0][0]);
	fclose(f);
}
Пример #7
0
   void getelm_c ( SpiceInt         frstyr,
                   SpiceInt         lineln,
                   const void     * lines,
                   SpiceDouble    * epoch,
                   SpiceDouble    * elems   ) 
/*

-Brief_I/O
 
   VARIABLE  I/O  DESCRIPTION 
   --------  ---  -------------------------------------------------- 
   frstyr     I   Year of earliest representable two-line elements.
   lineln     I   Length of strings in lines array.
   lines      I   A pair of "lines" containing two-line elements.
   epoch      O   The epoch of the elements in seconds past J2000. 
   elems      O   The elements converted to SPICE units. 
 
-Detailed_Input
 
   frstyr    is the first year possible for two line elements. Since
             two line elements allow only two digits for the year, some
             conventions must be followed concerning which century the
             two digits refer to.  frstyr is the year of the earliest
             representable elements. The two-digit year is mapped to
             the year in the interval from frstyr to frstyr + 99 that
             has the same last two digits as the two digit year in the
             element set.  For example if frstyr is set to 1960  then
             the two digit years are mapped as shown in the table
             below:
 
             Two-line         Maps to 
             element year 
             
                00            2000 
                01            2001 
                02            2002 
                 .              . 
                 .              . 
                 .              . 
                58            2058 
                59            2059 
               -------------------- 
                60            1960 
                61            1961 
                62            1962 
                 .              . 
                 .              . 
                 .              . 
                99            1999 
 
              Note that if Space Command should decide to represent
              years in 21st century as 100 + the last two digits of the
              year (for example: 2015 is represented as 115) instead of
              simply dropping the first two digits of the year, this
              routine will correctly map the year as long as you set
              frstyr to some value between 1900 and 1999.
 
   lines      is a pair of lines of text that comprise a Space command
              ``two-line element'' set.  lines should be declared
              
                 SpiceChar lines[2][lineln];

              These text lines should be the same as they are presented
              in the two-line element files available from Space
              Command (formerly NORAD). Below is an example of a
              two-line set for TOPEX.
 
   TOPEX 
   1 22076U 92052A   97173.53461370 -.00000038  00000-0  10000-3 0   594 
   2 22076  66.0378 163.4372 0008359 278.7732  81.2337 12.80930736227550 
 
 
                 
 
-Detailed_Output
 
   epoch      is the epoch of the two line elements supplied via 
              the input array lines.  Epoch is returned in TDB 
              seconds past J2000. 
 
   elems      is an array containing the elements from the two line 
              set supplied via the array lines.  The elements are 
              in units suitable for use by the CSPICE routine 
              ev2lin_. 
 
              Also note that the elements XNDD6O and BSTAR 
              incorporate the exponential factor present in the 
              input two line elements in LINES.  (See particulars 
              below. 
 
                  ELEMS [ 0 ] = XNDT2O in radians/minute**2 
                  ELEMS [ 1 ] = XNDD6O in radians/minute**3 
                  ELEMS [ 2 ] = BSTAR 
                  ELEMS [ 3 ] = XINCL  in radians 
                  ELEMS [ 4 ] = XNODEO in radians 
                  ELEMS [ 5 ] = EO 
                  ELEMS [ 6 ] = OMEGAO in radians 
                  ELEMS [ 7 ] = XMO    in radians 
                  ELEMS [ 8 ] = XNO    in radians/minute 
                  ELEMS [ 9 ] = EPOCH of the elements in seconds 
                                past ephemeris epoch J2000. 
 
-Parameters
 
   None. 
 
-Exceptions
 
   No checking of the inputs is performed in this routine. However, this
   routine does call other CSPICE routines. If one of these routines
   detects an error it will diagnose it and signal an error.
 
-Files
 
   You must have loaded a SPICE leapseconds kernel into the 
   kernel pool prior to caling this routine. 
 
-Particulars
 
   This routine parses a Space Command Two-line element set and returns
   the orbital elements properly scaled and in units suitable for use
   by other SPICE software.  Input elements look like the following
 
--------------------------------------------------------------------- 
1 22076U 92052A   97173.53461370 -.00000038  00000-0  10000-3 0   594 
2 22076  66.0378 163.4372 0008359 278.7732  81.2337 12.80930736227550 
--------------------------------------------------------------------- 
^ 
123456789012345678901234567890123456789012345678901234567890123456789 
         1         2         3         4         5         6 
 
   The ``raw'' elements in the first and second lines are marked below.
   Note that in several instances exponents and decimal points are
   implied.  Also note that input units are degrees, degrees/day**n and
   revolutions/day.
 
 
                    DAY OF YEAR             NDD60    BSTAR 
                    vvvvvvvvvvvv            vvvvvv   vvvvvv 
--------------------------------------------------------------------- 
1 22076U 92052A   97173.53461370 -.00000038  00000-0  10000-3 0   594 
--------------------------------------------------------------------- 
                  ^^             ^^^^^^^^^^       ^^       ^^ 
                  YEAR             NDT20          IEXP     IBEXP 
 
 
 
   The ``raw'' elements in the second line are marked below 
                 NODE0            OMEGA             N0 
                 vvvvvvvv         vvvvvvvv          vvvvvvvvvvv 
--------------------------------------------------------------------- 
2 22076  66.0378 163.4372 0008359 278.7732  81.2337 12.80930736227550 
--------------------------------------------------------------------- 
        ^^^^^^^^          ^^^^^^^          ^^^^^^^^ 
        Inclination       Eccentricity     M0 
 
   This routine extracts these values ``inserts'' the implied 
   decimal points and exponents and then converts the inputs 
   to units of radians, radians/minute, radians/minute**2, and 
   radians/minute**3 
 
-Examples
 
   Suppose you have a set of two-line elements and an array containing
   the related geophysical constants necessary to evaluate a state.
   The example below shows how you can use this routine together with
   the routine EV2LIN to propagate a state to an epoch of interest.
 
      #include <string.h>
      #include <stdio.h>
      #include "SpiceUsr.h"
      
      SpiceDouble         et;
      SpiceDouble         epoch;
      SpiceInt            frstyr;
          .
          .
          .
      /.
      The parameters below will make it easier to make assignments 
      to the array GEOPHS required by EV2LIN. 
 
         J2  --- location of J2 
         J3  --- location of J3 
         J4  --- location if J4 
         KE  --- location of KE = sqrt(GM) in eart-radii**1.5/MIN 
         QO  --- location of upper bound of atmospheric model in KM 
         SO  --- location of lower bound of atmospheric model in KM 
         ER  --- location of earth equatorial radius in KM. 
         AE  --- location of distance units/earth radius 
      ./
      
      #define  J2 0   
      #define  J3 1   
      #define  J4 2    
      #define  KE 3   
      #define  QO 4   
      #define  SO 5   
      #define  ER 6   
      #define  AE 7  
 
      /.
      We set the lower bound for the years to be the beginning 
      of the space age. 
      ./
      frstyr  =  1957;
 
      /.
      Read in the next two lines from the text file that contains 
      the two-line elements.  We assume that file has been opened 
      properly and that we have set the ``file pointer'' to the 
      correct location for reading the next set of elements. 
      ./
      
      for ( i = 0; i < 2; i++ )
      {
         fgets ( line[i], lineln, textfile );
         line[i][ strlen(line[i]) ] = '\0';
      }

      getelm_c ( frstyr, lineln, line, &epoch, elems ); 
 
 
      /.
      Set up the geophysical quantities.  At last check these 
      were the values used by Space Command. 
      ./
      
      geophs[ J2 ] =    1.082616e-3; 
      geophs[ J3 ] =   -2.53881e-6; 
      geophs[ J4 ] =   -1.65597e-6; 
      geophs[ KE ] =    7.43669161e-2; 
      geophs[ QO ] =  120.0; 
      geophs[ SO ] =   78.0; 
      geophs[ ER ] = 6378.135; 
      geophs[ AE ] =    1.0; 
      
      
      /.
      Now propagate the state using ev2lin_ to the epoch of 
      interest. 
      ./
      ev2lin_ ( &et, geophs, elems, state ); 
 
 
-Restrictions
 
  The format of the two-line elements suffer from a "millenium"
  problem---only two digits are used for the year of the elements. It
  is not clear how Space Command will deal with this problem as the
  year 2000 comes and goes.  We hope that by adjusting the input frstyr
  you should be able to use this routine well into the 21st century.
  However, since we can't predict how others will resolve the millenium
  problem we can't be sure that our approach will be addequate to deal
  with the problem.
 
  The approach taken to mapping the two-digit year to the full year is
  given by the code below. Here, yr is the integer obtained by parsing
  the two-digit year from the first line of the elements.
 
      begyr = (frstyr/100)*100; 
      year  = begyr + yr;
 
      if ( year < frstyr )  
      {
         year += 100;
      }
 
   This mapping will be changed if future two-line element
   representations make this method of computing the full year
   inaccurate.
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman    (JPL)
   W.L. Taber      (JPL) 
 
-Version

   -CSPICE Version 1.0.1, 15-NOV-2007 (EDW)
   
      Minor edits to example section; the getelm_c call lacked
      the 'lineln' argument, the use of 'et' implied a pointer
      rather than a value.

   -CSPICE Version 1.0.0, 06-AUG-1999 (NJB) (WLT)

-Index_Entries
 
   Parse two-line elements 
 
-&
*/

{ /* Begin getelm_c */


   /*
   Local constants
   */
   #define NELTS           2
   
   
   /*
   Local variables
   */
   SpiceChar            ** cvalsPtr;
   SpiceChar             * fCvalsArr;

   SpiceInt                i;
   SpiceInt                fCvalsLen;

   SpiceStatus             status;

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


   /*
   Check the input line array for null pointer of insufficient string
   length.
   */
   CHKOSTR ( CHK_STANDARD, "getelm_c", lines, lineln );


   /*
   Convert the input string array to a Fortran-style string 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 )
   {
      setmsg_c ( "Failure on malloc call to create pointer array "
                 "for line values."                              );
      sigerr_c ( "SPICE(MALLOCFAILED)"                           );
      chkout_c ( "getelm_c"                                      );
      return;
   }
   
   for ( i = 0;  i < NELTS;  i++  )
   {
      cvalsPtr[i] =  (SpiceChar *)lines  +  ( i * lineln );
   }
   
   status = C2F_CreateStrArr (  NELTS, 
                                ( ConstSpiceChar ** ) cvalsPtr, 
                                &fCvalsLen, 
                                &fCvalsArr                      );
  /* fCvalsArr[2*fCvalsLen] = '\0'; */
   
   if ( status == SPICEFAILURE )
   {
      free ( cvalsPtr );
      
      setmsg_c ( "C to Fortran string array conversion for `lines' "
                 "failed."                                           );
      sigerr_c ( "SPICE(STRINGCONVERROR)"                            );
      chkout_c ( "getelm_c"                                          );
      return;
   }
   
   /*
   Call the f2c'd routine.
   */
   getelm_ (  ( integer    * ) &frstyr,
              ( char       * ) fCvalsArr,
              ( doublereal * ) epoch,
              ( doublereal * ) elems,
              ( ftnlen       ) fCvalsLen  );
   
   /*
   Clean up all of our dynamically allocated arrays.
   */
   free ( cvalsPtr  );
   free ( fCvalsArr );


   chkout_c ( "getelm_c" );

} /* End getelm_c */
Пример #8
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 */
Пример #9
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 */
Пример #10
0
   void repmi_c ( ConstSpiceChar     * in,
                  ConstSpiceChar     * marker,
                  SpiceInt             value,
                  SpiceInt             lenout,
                  SpiceChar          * out     ) 

/*

-Brief_I/O
 
   VARIABLE  I/O  DESCRIPTION 
   --------  ---  -------------------------------------------------- 
   in         I   Input string. 
   marker     I   Marker to be replaced. 
   value      I   Replacement value.
   lenout     I   Available space in output string.
   out        O   Output string. 
   MAXLI      P   Maximum length of an integer. 
 
-Detailed_Input
 
   in             is an arbitrary character string. 
 
   marker         is an arbitrary character string. The first occurrence 
                  of marker in the input string is to be replaced by value. 
 
                  Leading and trailing blanks in marker are NOT significant. 
                  In particular, no substitution is performed if marker 
                  is blank. 
 
   value          is an arbitrary integer. 

 
   lenout         is the allowed length of the output string.  This length
                  must large enough to hold the output string plus the
                  terminator.  If the output string is expected to have x
                  characters, lenout should be at least x + 1.

-Detailed_Output
 
   out            is the string obtained by substituting the text 
                  representation of value for the first occurrence 
                  of marker in the input string. 
 
                  out and in must be identical or disjoint. 
 
-Parameters
 
   MAXLI          is the maximum expected length of the text 
                  representation of an integer. 11 characters are 
                  sufficient to hold any integer whose absolute 
                  value is less than 10 billion. 
 
                  This routine assumes that the input integer
                  is such that its string representation contains
                  no more than MAXLI characters.
 
-Files
 
   None. 
 
-Exceptions
 
   1) The error SPICE(NULLPOINTER) is signaled if any of 
      the input or output string pointers is null.

   2) If the marker string is blank or empty, this routine leaves 
      the input string unchanged, except that trailing blanks
      will be trimmed.  This case is not considered an error.

   3) If the output string is too short to accommodate a terminating
      null character, the error SPICE(STRINGTOOSHORT) is signaled.

   4) If out does not have sufficient length to accommodate the 
      result of the substitution, the result will be truncated on 
      the right. 
  
-Particulars
 
   This is one of a family of related routines for inserting values 
   into strings. They are typically to construct messages that 
   are partly fixed, and partly determined at run time. For example, 
   a message like 
 
      "Fifty-one pictures were found in directory [USER.DATA]." 
 
   might be constructed from the fixed string 
 
      "#1 pictures were found in directory #2." 
 
   by the calls 
 
      #include "SpiceUsr.h"
           .
           .
           .
      #define   LENOUT                  81
           .
           .
           .
      repmct_c ( string, "#1",  51,  'c',      LENOUT, string );
      repmc_c  ( string, "#2", "[USER.DATA]",  LENOUT, string );
 

   which substitute the cardinal text "Fifty-one" and the character 
   string "[USER.DATA]" for the markers "#1" and "#2" respectively. 
 
   The complete list of routines is shown below. 
 
      repmc_c  ( Replace marker with character string value ) 
      repmd_c  ( Replace marker with double precision value ) 
      repmf_c  ( Replace marker with formatted d.p. value   ) 
      repmi_c  ( Replace marker with integer value          ) 
      repmct_c ( Replace marker with cardinal text          ) 
      repmot_c ( Replace marker with ordinal text           ) 

 
-Examples
 
   1. Let 
 
         in == "Invalid operation value.  The value was <opcode>." 
 
      Then following the call, 
 
         #include "SpiceUsr.h"
              .
              .
              .
         #define   LENOUT                  201
              .
              .
              .
         repmi_c ( in, "<opcode>", 5, LENOUT, outstr );
 

      outstr contains the string: 
 
         "Invalid operation value.  The value was 5." 
 
 

   2. Let 
 
         in ==  "Left endpoint exceeded right endpoint.  "
                "The left endpoint was:  XX.  The right "
                "endpoint was:  XX." 
 
      Then following the call, 
 
 
         #include "SpiceUsr.h"
              .
              .
              .
         #define   LENOUT                  201
              .
              .
              .
         repmi_c ( in, "  XX  ", 5, LENOUT, out );
 
      out is 
 
         "Left endpoint exceeded right endpoint.  The left "
         "endpoint was:  5.  The right endpoint was:  XX."
 
 
   3. Let 
 
         num    == 23 
         chance == "fair" 
         score  == 4.665 
 
      Then following the sequence of calls, 
 
         #include "SpiceUsr.h"
              .
              .
              .
         #define   LENOUT                  201
              .
              .
              .
         repmi_c ( "There are & routines that have a "  
                   "& chance of meeting your needs."    
                   "The maximum score was &.", 
                   "&",
                    num, 
                    LENOUT,
                    msg                              ); 
 
         repmc_c ( msg, marker, chance, LENOUT, msg );
 
         repmf_c ( msg, marker, score,  4, 'f', LENOUT, msg ); 
 

      msg is 
 
         "There are 23 routines that have a fair chance of "
         "meeting your needs.  The maximum score was 4.665." 
 
-Restrictions
 
   None. 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman   (JPL) 
   I.M. Underwood (JPL) 
 
-Version
 
   -CSPICE Version 1.0.0, 14-AUG-2002 (NJB) (IMU)

-Index_Entries
 
   replace marker with integer 
 
-&
*/

{ /* Begin repmi_c */


   /*
   Local variables 
   */
   ConstSpiceChar        * markPtr;


   /*
   Use discovery check-in. 

   Make sure no string argument pointers are null.
   */
   CHKPTR( CHK_DISCOVER, "repmi_c", in     );
   CHKPTR( CHK_DISCOVER, "repmi_c", marker );
   CHKPTR( CHK_DISCOVER, "repmi_c", out    );


   /*
   If the output string can't hold a terminating null character,
   we can't proceed. 
   */
   if ( lenout < 1 )
   {
      chkin_c  ( "repmi_c"                                    );
      setmsg_c ( "String length lenout must be >= 1; actual "
                 "value = #."                                 );
      errint_c ( "#", lenout                                  );
      sigerr_c ( "SPICE(STRINGTOOSHORT)"                      );
      chkout_c ( "repmi_c"                                    );
      return;
   }


   /*
   If the output string has no room for data characters, we simply
   terminate the string.
   */
   if ( lenout == 1 )
   {
      out[0] = NULLCHAR;
      return;
   }


   /*
   If the input string has zero length, the output is empty as well. 
   */
   if ( in[0] == NULLCHAR )
   {
      out[0] = NULLCHAR;

      return;
   }


   /*
   If the marker is empty, pass a blank marker to the f2c'd routine.
   Otherwise, pass in the marker.
   */
   if ( marker[0] == NULLCHAR )
   {
      markPtr = " ";
   }
   else
   {
      markPtr = marker;
   }
   
   /*
   Simply call the f2c'd routine. 
   */
   repmi_ ( ( char     * ) in,
            ( char     * ) markPtr,
            ( integer  * ) &value,
            ( char     * ) out,
            ( ftnlen     ) strlen(in),
            ( ftnlen     ) strlen(markPtr),
            ( ftnlen     ) lenout-1         );

   /*
   Convert the output string from Fortran to C style. 
   */
   F2C_ConvertStr ( lenout, out );
   

} /* End repmi_c */
Пример #11
0
   void mxmg_c ( const void    * m1,
                 const void    * m2,
                 SpiceInt        nrow1,
                 SpiceInt        ncol1,
                 SpiceInt        ncol2,
                 void          * mout   )
/*

-Brief_I/O

   VARIABLE  I/O  DESCRIPTION
   --------  ---  --------------------------------------------------
   m1         I   nrow1 X ncol1 double precision matrix.
   m2         I   ncol1 X ncol2 double precision matrix.
   nrow1      I   Row dimension of m1 (and also mout).
   ncol1      I   Column dimension of m1 and row dimension of m2.
   ncol2      I   Column dimension of m2 (and also mout).
   mout       O   nrow1 X ncol2 double precision matrix.

-Detailed_Input

   m1         is any double precision matrix of arbitrary size.

   m2         is any double precision matrix of arbitrary size.
              The number of rows in m2 must match the number of
              columns in m1.

   nrow1      is the number of rows in both m1 and mout.

   ncol1      is the number of columns in m1 and (by necessity)
              the number of rows of m2.

   ncol2      is the number of columns in both m2 and mout.

-Detailed_Output

   mout
              mout is the product matrix defined by

                 mout = (m1) x (m2)

              mout is a double precision matrix of dimension nrow1 x
              ncol2.

              mout may overwrite m1 or m2.  Note that this capability
              does not exist in the Fortran version of SPICELIB; in the
              Fortran version, the output must not overwrite either
              input.
-Parameters

   None.

-Exceptions

   1) If dynamic allocation of memory fails, the error
      SPICE(MEMALLOCFAILED) is signalled.

-Files

   None.

-Particulars

   The code reflects precisely the following mathematical expression

   For each value of the subscript i from 1 to nrow1, and j from 1
   to ncol2:

      mout(i,j) = Summation from k=1 to ncol1 of  m1(i,k) * m2(k,j)


-Examples


   Let

      m1 = | 1.0  4.0 |    and  m2 =  | 1.0  3.0  5.0 |
           |          |                               |
           | 2.0  5.0 |               | 2.0  4.0  6.0 |
           |          |
           | 3.0  6.0 |

   and

      nrow1  = 3
      ncol1  = 2
      ncol2  = 3

   Then the call


      mxmg ( m1, m2, nrow1, ncol1, ncol2, mout );


   produces the matrix

      mout = |  9.0  19.0  29.0 |
             |                  |
             | 12.0  26.0  40.0 |
             |                  |
             | 15.0  33.0  51.0 |


-Restrictions

   1) No error checking is performed to prevent numeric overflow or
      underflow.

   2) No error checking performed to determine if the input and
      output matrices have, in fact, been correctly dimensioned.

-Literature_References

   None.

-Author_and_Institution

   N.J. Bachman       (JPL)
   W.M. Owen          (JPL)

-Version

   -CSPICE Version 1.1.2, 16-JAN-2008   (EDW)

      Corrected typos in header titles:
      
      Detailed Input to Detailed_Input
      Detailed Output to Detailed_Output
      
   -CSPICE Version 1.1.1, 10-NOV-2006   (EDW)

      Added Parameters section header. 

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

      Const-qualified input arrays.

   -CSPICE Version 1.0.0, 16-APR-1999 (NJB)

-Index_Entries

   matrix times matrix n-dimensional_case

-&
*/

{  /* Begin mxmg_c */


   /*
   Local macros

   We'd like to be able to refer to the elements of the input and output
   matrices using normal subscripts, for example, m1[2][3].  Since the
   compiler doesn't know how to compute index offsets for the array
   arguments, which have user-adjustable size, we must compute the
   offsets ourselves.  To make syntax a little easier to read (we hope),
   we'll use macros to do the computations.

   The macro INDEX(width, i,j) computes the index offset from the array
   base of the element at position [i][j] in a 2-dimensional matrix
   having the number of columns indicated by width.  For example, if
   the input matrix m1 has 2 rows and 3 columns, the element at position
   [0][1] would be indicated by

      m1[ INDEX(3,0,1) ]

   */

   #define INDEX( width, row, col )     ( (row)*(width) + (col) )


   /*
   Local variables
   */
   SpiceDouble             innerProduct;
   SpiceDouble            *tmpmat;
   SpiceDouble            *loc_m1;
   SpiceDouble            *loc_m2;

   SpiceInt                col;
   SpiceInt                nelts;
   SpiceInt                row;
   SpiceInt                i;

   size_t                  size;


   /*
   Allocate space for a temporary copy of the output matrix, which
   has nrow1 rows and ncol2 columns.
   */
   nelts   =  nrow1 * ncol2;
   size    =  (size_t) ( nelts * sizeof(SpiceDouble) );

   tmpmat  =  (SpiceDouble *) malloc ( size );

   if ( tmpmat == (SpiceDouble *)0 )
   {
      chkin_c  ( "mxmg_c"                                          );
      setmsg_c ( "An attempt to create a temporary matrix failed." );
      sigerr_c ( "SPICE(MEMALLOCFAILED)"                           );
      chkout_c ( "mxmg_c"                                          );
      return;
   }

   /*
   Cast the input pointers to pointers to SpiceDoubles.  Note:  the
   original variables are pointers to void so that callers may
   supply the array names as arguments without casting them to
   SpiceDoubles.  The naked array name is considered by the compiler
   to be an incompatible pointer type with (SpiceDouble *), so we
   can't simply declare the arguments to be (SpiceDouble *).  On the
   other hand, every pointer type can be cast to (void *).
   */

   loc_m1 = (SpiceDouble *) m1;
   loc_m2 = (SpiceDouble *) m2;


   /*
   Compute the product.  The matrix element at position (row,col) is
   the inner product of the row of m1 having index row and the
   column of m2 having index col.  We compute index offsets using
   the macro INDEX.
   */

   for ( row = 0;  row < nrow1;  row++ )
   {

      for ( col = 0;  col < ncol2;  col++ )
      {
         innerProduct = 0.0;

         for ( i = 0;  i < ncol1;  i++ )
         {
            innerProduct  +=    loc_m1[ INDEX(ncol1,  row, i  ) ]
                              * loc_m2[ INDEX(ncol2,  i,   col) ];
         }

         tmpmat [ INDEX( ncol2, row, col ) ]  =  innerProduct;
      }
   }

   /*
   Move the result from tmpmat into mout.
   */
   MOVED ( tmpmat, nelts, mout );

   /*
   Free the temporary matrix.
   */
   free ( tmpmat );


} /* End mxmg_c */
Пример #12
0
int main(int ac, char** av)
{   
   /* Constants */
   #define PBUFSIZ         10000
   #define FILSIZ          256

   /* Local variables */
   SpiceBoolean            found;

   SpiceChar               dsk  [ FILSIZ ];

   SpiceDLADescr           dladsc;

   SpiceDouble             normal [3];
   SpiceDouble             verts  [3][3];
   SpiceDouble             BoundRadius;

   SpiceInt                handle;
   SpiceInt                i;
   SpiceInt                j;
   SpiceInt                n;
   SpiceInt                np;
   SpiceInt                nread;
   SpiceInt                nv;
   SpiceInt                nvtx;
   SpiceInt                plates[PBUFSIZ][3];
   SpiceInt                plix;
   SpiceInt                remain;
   SpiceInt                start;
   int iAc;
   int doMdl = 1;

   /* Prompt for name of DSK and open file for reading.  */
   *dsk = '\0';
   for (iAc=1; iAc<ac; ++iAc) {
     if ( strcmp(av[iAc], "--wrl") ) {
       strncpy(dsk,av[1],FILSIZ);
       continue;
     } else {
       doMdl = 0;
     }
   }
   if ( ! *dsk) {
     if ( doMdl ) {
       prompt_c ( "### Enter DSK (*.bds) filepath > ", FILSIZ, dsk );
     } else {
       fprintf( stderr, "### Enter DSK (*.bds) filepath > " );
       prompt_c ( "", FILSIZ, dsk );
     }
   }

   dasopr_c ( dsk,    &handle );

   dlabfs_c ( handle, &dladsc, &found );

   if ( !found )
   { 
      setmsg_c ( "No segment found in file #." );
      errch_c  ( "#",  dsk                     );
      sigerr_c ( "SPICE(NOSEGMENT)"            );
   }

   /* Get segment vertex and plate counts.  */
   dskz02_c ( handle, &dladsc, &nv, &np );

   /*******************************************************************/
   if ( doMdl ) {
     printf( "\
### File:  %s\n\
Component DSK\n\
  PolygonMesh\n\
    FaceColor %%255255255\n\
    SmoothShading No\n\
    BackfaceCullable Yes\n\
    Translucency 0.5\n\
    Specularity 0.59375000\n\
    Shininess 76.000000\n\
\n\
    NumVerts %d\n\
    Data\n", dsk, nv );
   } else {
Пример #13
0
   void insrti_c ( SpiceInt        item,
                   SpiceCell     * set  )

/*

-Brief_I/O
 
   VARIABLE  I/O  DESCRIPTION 
   --------  ---  -------------------------------------------------- 
   item       I   Item to be inserted. 
   set       I/O  Insertion set. 
 
-Detailed_Input
 
   item        is an item which is to be inserted into the 
               specified set. item may or may not already 
               be an element of the set. 


   set         is a CSPICE set.  set must be declared as an integer
               SpiceCell. 

               On input, set  may or may not contain the input item 
               as an element. 
 
-Detailed_Output

   set         on output contains the union of the input set and 
               the singleton set containing the input item.
 
-Parameters
 
   None. 
 
-Exceptions
 
   1) If the input set argument is a SpiceCell of type other than
      integer, the error SPICE(TYPEMISMATCH) is signaled.

   2) If the insertion of the element into the set causes an excess 
      of elements, the error SPICE(SETEXCESS) is signaled. 
 
   3) If the input set argument does not qualify as a CSPICE set, 
      the error SPICE(NOTASET) will be signaled.  CSPICE sets have
      their data elements sorted in increasing order and contain
      no duplicate data elements.

-Files
 
   None. 
 
-Particulars
 
   None. 
 
-Examples
 
   1) In the following example, the NAIF ID code of Pluto is removed from 
      the integer set planets and inserted into the integer set 
      asteroids. 

         #include "SpiceUsr.h"
                .
                .
                .
         /.
         Declare the sets with maximum number of elements MAXSIZ.
         ./
         SPICEINT_CELL ( planets,   MAXSIZ );
         SPICEINT_CELL ( asteroids, MAXSIZ );
                .
                .
                .
         removi_c ( 999, &planets   );
         insrti_c ( 999, &asteroids ); 


      If 999 is not an element of planets, then the contents of 
      planets are not changed. Similarly, if 999 is already an 
      element of asteroids, the contents of asteroids remain unchanged. 

-Restrictions
 
   None. 

-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 2.0.0, 01-NOV-2005 (NJB)

       Long error message was updated to include size of
       set into which insertion was attempted.
 
   -CSPICE Version 1.0.0, 07-AUG-2002 (NJB) (CAC) (WLT) (IMU)

-Index_Entries
 
   insert an item into an integer set 
 
-&
*/
{
   /*
   local variables
   */
   SpiceBoolean            inSet;
   
   SpiceInt                i;
   SpiceInt              * idata;
   SpiceInt                loc;


   /*
   Use discovery check-in. 
   */
   
   /*
   Make sure we're working with an integer cell. 
   */
   CELLTYPECHK ( CHK_DISCOVER, "insrti_c", SPICE_INT, set );

   idata = (SpiceInt *) (set->data);

   /*
   Make sure the cell is really a set. 
   */
   CELLISSETCHK ( CHK_DISCOVER, "insrti_c", set );
 
   /*
   Initialize the set if necessary. 
   */
   CELLINIT ( set );
 
   /*
   Is the item already in the set? If not, it needs to be inserted.
   */
   loc   =  lstlei_c ( item,  set->card,  idata );

   inSet =  (  loc  >  -1  ) && ( item == idata[loc] );
 
   if ( inSet )
   {
      return;
   }

   /*
   It's an error if the set has no room left. 
   */
   if ( set->card == set->size )
   {
      chkin_c  ( "insrti_c"                                       );
      setmsg_c ( "An element could not be inserted into the set "
                 "due to lack of space; set size is #."           );
      errint_c ( "#", set->size                                   );
      sigerr_c ( "SPICE(SETEXCESS)"                               );
      chkout_c ( "insrti_c"                                       );
      return;
   }

   /*
   Make room by moving the items that come after item in the set. 
   Insert the item after index loc.
   */
   
   for (  i = (set->card);   i > loc+1;   i--  )
   {
      idata[i] = idata[i-1];
   }

   idata[loc+1] = item;

   /*
   Increment the set's cardinality.
   */
   (set->card) ++;

   /*
   Sync the set. 
   */
   zzsynccl_c ( C2F, set );
}
Пример #14
0
   void npedln_c ( SpiceDouble         a,
                   SpiceDouble         b,
                   SpiceDouble         c,
                   ConstSpiceDouble    linept[3],
                   ConstSpiceDouble    linedr[3],
                   SpiceDouble         pnear[3],
                   SpiceDouble       * dist      ) 

/*

-Brief_I/O
 
   Variable  I/O  Description 
   --------  ---  -------------------------------------------------- 
   a          I   Length of ellipsoid's semi-axis in the x direction 
   b          I   Length of ellipsoid's semi-axis in the y direction 
   c          I   Length of ellipsoid's semi-axis in the z direction 
   linept     I   Point on line 
   linedr     I   Direction vector of line 
   pnear      O   Nearest point on ellipsoid to line 
   dist       O   Distance of ellipsoid from line 
 
-Detailed_Input
 
   a, 
   b, 
   c              are the lengths of the semi-axes of a triaxial 
                  ellipsoid which is centered at the origin and 
                  oriented so that its axes lie on the x-, y- and 
                  z- coordinate axes.  a, b, and c are the lengths of 
                  the semi-axes that point in the x, y, and z 
                  directions respectively. 
 
   linept 
   linedr         are, respectively, a point and a direction vector 
                  that define a line.  The line is the set of vectors 
 
                     linept   +   t * linedr 
 
                  where t is any real number. 
 
-Detailed_Output
 
   pnear          is the point on the ellipsoid that is closest to 
                  the line, if the line doesn't intersect the 
                  ellipsoid. 
 
                  If the line intersects the ellipsoid, pnear will 
                  be a point of intersection.  If linept is outside 
                  of the ellipsoid, pnear will be the closest point 
                  of intersection.  If linept is inside the 
                  ellipsoid, pnear will not necessarily be the 
                  closest point of intersection. 
 
 
   dist           is the distance of the line from the ellipsoid. 
                  This is the minimum distance between any point on 
                  the line and any point on the ellipsoid. 
 
                  If the line intersects the ellipsoid, dist is zero. 
 
-Parameters
 
   None.
    
-Exceptions
 
   If this routine detects an error, the output arguments nearp and 
   dist are not modified. 
 
   1)  If the length of any semi-axis of the ellipsoid is 
       non-positive, the error SPICE(INVALIDAXISLENGTH) is signaled. 
 
   2)  If the line's direction vector is the zero vector, the error 
       SPICE(ZEROVECTOR) is signaled. 
 
   3)  If the length of any semi-axis of the ellipsoid is zero after 
       the semi-axis lengths are scaled by the reciprocal of the 
       magnitude of the longest semi-axis and then squared, the error 
       SPICE(DEGENERATECASE) is signaled. 
 
   4)  If the input ellipsoid is extremely flat or needle-shaped 
       and has its shortest axis close to perpendicular to the input 
       line, numerical problems could cause this routine's algorithm 
       to fail, in which case the error SPICE(DEGENERATECASE) is 
       signaled. 
 
-Files
 
   None. 
 
-Particulars
 
   For any ellipsoid and line, if the line does not intersect the 
   ellipsoid, there is a unique point on the ellipsoid that is 
   closest to the line.  Therefore, the distance dist between 
   ellipsoid and line is well-defined.  The unique line segment of 
   length dist that connects the line and ellipsoid is normal to 
   both of these objects at its endpoints. 
 
   If the line intersects the ellipsoid, the distance between the 
   line and ellipsoid is zero. 
 
-Examples
 
   1)   We can find the distance between an instrument optic axis ray 
        and the surface of a body modelled as a tri-axial ellipsoid 
        using this routine.  If the instrument position and pointing 
        unit vector in body-fixed coordinates are 
 
           linept = ( 1.0e6,  2.0e6,  3.0e6 ) 
 
        and 
 
           linedr = ( -4.472091234e-1 
                      -8.944182469e-1, 
                      -4.472091234e-3  ) 
 
        and the body semi-axes lengths are 
 
           a = 7.0e5 
           b = 7.0e5 
           c = 6.0e5, 
 
        then the call to npedln_c 
 
           npedln_c ( a, b, c, linept, linedr, pnear, &dist ); 
 
        yields a value for pnear, the nearest point on the body to 
        the optic axis ray, of 

           (  -.16333110792340931E+04,
              -.32666222157820771E+04,
               .59999183350006724E+06  )
 
        and a value for dist, the distance to the ray, of 

           .23899679338299707E+06
 
        (These results were obtained on a PC-Linux system under gcc.)

        In some cases, it may not be clear that the closest point 
        on the line containing an instrument boresight ray is on 
        the boresight ray itself; the point may lie on the ray 
        having the same vertex as the boresight ray and pointing in 
        the opposite direction.  To rule out this possibility, we 
        can make the following test: 
 
           /.
           Find the difference vector between the closest point 
           on the ellipsoid to the line containing the boresight 
           ray and the boresight ray's vertex.  Find the 
           angular separation between this difference vector 
           and the boresight ray.  If the angular separation 
           does not exceed pi/2, we have the nominal geometry. 
           Otherwise, we have an error. 
           ./
           
           vsub_c ( pnear,  linept,  diff );
           
           sep = vsep_c ( diff, linedr );

           if (  sep <= halfpi_c()  )  
           {
              [ perform normal processing ] 
           }
           else 
           {
              [ handle error case ] 
           }

 
-Restrictions
 
   None. 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman   (JPL) 
 
-Version
 
   -CSPICE Version 1.1.0, 01-JUN-2010 (NJB)
 
       Added touchd_ calls to tests for squared, scaled axis length
       underflow. This forces rounding to zero in certain cases where
       it otherwise might not occur due to use of extended registers.

   -CSPICE Version 1.0.1, 06-DEC-2002 (NJB)

       Outputs shown in header example have been corrected to 
       be consistent with those produced by this routine.

   -CSPICE Version 1.0.0, 03-SEP-1999 (NJB)

-Index_Entries
 
   distance between line and ellipsoid 
   distance between line of sight and body 
   nearest point on ellipsoid to line 
 
-&
*/

{ /* Begin npedln_c */



   /*
   Local variables
   */ 
 
   SpiceBoolean            found  [2];
   SpiceBoolean            ifound;
   SpiceBoolean            xfound;

   SpiceDouble             oppdir [3];
   SpiceDouble             mag;
   SpiceDouble             normal [3];
   SpiceDouble             prjpt  [3];
   SpiceDouble             prjnpt [3];
   SpiceDouble             pt     [2][3];
   SpiceDouble             scale;
   SpiceDouble             scla;
   SpiceDouble             scla2;
   SpiceDouble             sclb;
   SpiceDouble             sclb2;
   SpiceDouble             sclc;
   SpiceDouble             sclc2;
   SpiceDouble             sclpt  [3];
   SpiceDouble             udir   [3];

   SpiceEllipse            cand;
   SpiceEllipse            prjel;
   
   SpiceInt                i;

   SpicePlane              candpl;
   SpicePlane              prjpl;


   /*
   Static variables
   */


   /*
   Participate in error tracing.
   */

   chkin_c ( "npedln_c" );



   /*
   The algorithm used in this routine has two parts.  The first
   part handles the case where the input line and ellipsoid
   intersect.  Our procedure is simple in that case; we just
   call surfpt_c twice, passing it first one ray determined by the
   input line, then a ray pointing in the opposite direction.
   The second part of the algorithm handles the case where surfpt_c
   doesn't find an intersection.

   Finding the nearest point on the ellipsoid to the line, when the
   two do not intersect, is a matter of following four steps:

   1)  Find the points on the ellipsoid where the surface normal
       is normal to the line's direction.  This set of points is
       an ellipse centered at the origin.  The point we seek MUST
       lie on this `candidate' ellipse.

   2)  Project the candidate ellipse onto a plane that is normal
       to the line's direction.  This projection preserves
       distance from the line; the nearest point to the line on
       this new ellipse is the projection of the nearest point to
       the line on the candidate ellipse, and these two points are
       exactly the same distance from the line.  If computed using
       infinite-precision arithmetic, this projection would be
       guaranteed to be non-degenerate as long as the input
       ellipsoid were non-degenerate.  This can be verified by
       taking the inner product of the scaled normal to the candidate
       ellipse plane and the line's unitized direction vector
       (these vectors are called normal and udir in the code below);
       the inner product is strictly greater than 1 if the ellipsoid
       is non-degenerate.

   3)  The nearest point on the line to the projected ellipse will
       be contained in the plane onto which the projection is done;
       we find this point and then find the nearest point to it on
       the projected ellipse.  The distance between these two points
       is the distance between the line and the ellipsoid.

   4)  Finally, we find the point on the candidate ellipse that was
       projected to the nearest point to the line on the projected
       ellipse that was found in step 3.  This is the nearest point
       on the ellipsoid to the line.



                    Glossary of Geometric Variables


          a,
          b,
          c           Input ellipsoid's semi-axis lengths.

          point       Point of intersection of line and ellipsoid
                      if the intersection is non-empty.

          candpl      Plane containing candidate ellipse.

          normal      Normal vector to the candidate plane candpl.

          cand        Candidate ellipse.

          linept,
          linedr,     Point and direction vector on input line.

          udir        Unitized line direction vector.

          prjpl       Projection plane; the candidate ellipse is
                      projected onto this plane to yield prjel.

          prjel       Projection of the candidate ellipse cand onto
                      the projection plane prjel.

          prjpt       Projection of line point.

          prjnpt      Nearest point on projected ellipse to
                      projection of line point.

          pnear       Nearest point on ellipsoid to line.

   */
 
 
 
   /*
   We need a valid normal vector.
   */
   
   unorm_c ( linedr, udir, &mag );

   if ( mag == 0. )
   {
      setmsg_c( "Line direction vector is the zero vector. " );
      sigerr_c( "SPICE(ZEROVECTOR)"                          );
      chkout_c( "npedln_c"                                   );
      return;
   }


   if (         ( a <= 0. )            
          ||    ( b <= 0. )            
          ||    ( c <= 0. )   )    
   {
      setmsg_c  ( "Semi-axis lengths: a = #,  b = #,  c = #."  );
      errdp_c   ( "#", a                                       );
      errdp_c   ( "#", b                                       );
      errdp_c   ( "#", c                                       );
      sigerr_c  ( "SPICE(INVALIDAXISLENGTH)"                   );
      chkout_c  ( "npedln_c"                                   );
      return;
   }


   /*
   Scale the semi-axes lengths for better numerical behavior.
   If squaring any one of the scaled lengths causes it to
   underflow to zero, we cannot continue the computation. Otherwise,
   scale the viewing point too.
   */

   scale  =  maxd_c ( 3, a, b, c );

   scla   =  a / scale;
   sclb   =  b / scale;
   sclc   =  c / scale;

   scla2  =  scla*scla;
   sclb2  =  sclb*sclb;
   sclc2  =  sclc*sclc;

   if (       ( (SpiceDouble)touchd_(&scla2)   ==   0. )
         ||   ( (SpiceDouble)touchd_(&sclb2)   ==   0. )
         ||   ( (SpiceDouble)touchd_(&sclc2)   ==   0. )   )    
   {
      setmsg_c ( "Semi-axis too small:  a = #, b = #, c = #. " );
      errdp_c  ( "#", a                                        );
      errdp_c  ( "#", b                                        );
      errdp_c  ( "#", c                                        );
      sigerr_c ( "SPICE(DEGENERATECASE)"                       );
      chkout_c ( "npedln_c"                                    );
      return;
   }

 
   /*
   Scale linept.
   */
   sclpt[0]  =  linept[0] / scale;
   sclpt[1]  =  linept[1] / scale;
   sclpt[2]  =  linept[2] / scale;
 
   /*
   Hand off the intersection case to surfpt_c.  surfpt_c determines
   whether rays intersect a body, so we treat the line as a pair
   of rays.
   */

   vminus_c ( udir, oppdir );

   surfpt_c ( sclpt, udir,   scla, sclb, sclc, pt[0], &(found[0]) );
   surfpt_c ( sclpt, oppdir, scla, sclb, sclc, pt[1], &(found[1]) );

   for ( i = 0;  i < 2;  i++ )
   {
      if ( found[i] ) 
      {
         *dist  =  0.0;

         vequ_c   ( pt[i],  pnear         );
         vscl_c   ( scale,  pnear,  pnear );
         chkout_c ( "npedln_c"            );
         return;
      }
   }


   /*
   Getting here means the line doesn't intersect the ellipsoid.

   Find the candidate ellipse CAND.  NORMAL is a normal vector to
   the plane containing the candidate ellipse.   Mathematically the
   ellipse must exist, since it's the intersection of an ellipsoid
   centered at the origin and a plane containing the origin.  Only
   numerical problems can prevent the intersection from being found.
   */

   normal[0]  =  udir[0] / scla2;
   normal[1]  =  udir[1] / sclb2;
   normal[2]  =  udir[2] / sclc2;

   nvc2pl_c ( normal, 0., &candpl );

   inedpl_c ( scla, sclb, sclc, &candpl, &cand, &xfound );

   if ( !xfound ) 
   {
      setmsg_c ( "Candidate ellipse could not be found."  );
      sigerr_c ( "SPICE(DEGENERATECASE)"                  );
      chkout_c ( "npedln_c"                               );
      return;
   }
   
   /*
   Project the candidate ellipse onto a plane orthogonal to the
   line.  We'll call the plane prjpl and the projected ellipse prjel.
   */
   nvc2pl_c ( udir,   0.,     &prjpl );
   pjelpl_c ( &cand,  &prjpl, &prjel );
 
 
   /*
   Find the point on the line lying in the projection plane, and
   then find the near point PRJNPT on the projected ellipse.  Here
   PRJPT is the point on the line lying in the projection plane.
   The distance between PRJPT and PRJNPT is DIST.
   */

   vprjp_c  ( sclpt,   &prjpl,  prjpt         );
   npelpt_c ( prjpt,   &prjel,  prjnpt,  dist );
 
   
   /*
   Find the near point pnear on the ellipsoid by taking the inverse
   orthogonal projection of prjnpt; this is the point on the
   candidate ellipse that projects to prjnpt.  Note that the
   output dist was computed in step 3 and needs only to be re-scaled.

   The inverse projection of pnear ought to exist, but may not
   be calculable due to numerical problems (this can only happen
   when the input ellipsoid is extremely flat or needle-shaped).
   */
   
   vprjpi_c ( prjnpt, &prjpl, &candpl, pnear, &ifound );
 
   if ( !ifound )
   {
      setmsg_c ( "Inverse projection could not be found."  );
      sigerr_c ( "SPICE(DEGENERATECASE)"                   );
      chkout_c ( "npedln_c"                                );
      return;
   }
 
   /*
   Undo the scaling.
   */
   
   vscl_c ( scale,  pnear,  pnear );

   *dist *= scale;
 
 
   chkout_c ( "npedln_c" );

} /* End npedln_c */
Пример #15
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 */
Пример #16
0
   void errprt_c ( ConstSpiceChar * op,
                   SpiceInt         lenout,
                   SpiceChar      * list  )

/*

-Brief_I/O

   VARIABLE  I/O  DESCRIPTION
   --------  ---  --------------------------------------------------
   op         I   The operation:  "GET" or "SET".
   lenout     I   Length of list for output.
   list      I/O  Specification of error messages to be output.

-Detailed_Input

   op      indicates the operation to be performed.  Possible
           values are "GET" and "SET".

           "SET" means, "the following list specifies the default
           selection of error messages to be output."  These are
           the messages that will be output to the default error
           output device (selected by errdev_c) when an error is
           detected.

           "GET" means, "return the current list of error output
           items."  This is the exact list that was set by the
           last call to this routine with the "SET" option.

           The option can be specified in mixed case.  For example,
           the following call will work:

           errprt_c ( "SeT", lenout, "ALL" )


   lenout  is the allowed length of list when list is returning a
           the error message list.  The size described by lenout
           should be large enough to hold any possible output plus 1.


   list    is a list of error message items.  The items
           are delimited by commas.  The items that can be
           in the list are the words:

           1.  SHORT        ...indicates the short error message
           2.  EXPLAIN      ...the explanation of the short message
           3.  LONG         ...the long error message
           4.  TRACEBACK    ...the traceback
           5.  ALL          ...indicates "output all messages"
           6.  NONE         ...indicates "don't output any messages"
           7.  DEFAULT      ...same as ALL, but includes default
                                message

           A "list" is a character string containing some or
           all of the above words, delimited by commas.  Examples
           are:

           1.  "SHORT, EXPLAIN"
           2.  "SHORT, LONG"
           3.  "ALL"
           4.  "NONE"
           5.  "ALL, NONE, ALL, SHORT, NONE"

           Each word in the list can be thought of as
           "flipping a switch" to enable or disable the output
           of the message(s) indicated by the word.  The
           words are acted on in the order they occur in the
           list, starting with the leftmost word.  As examples,
           consider the sample lists above.

           The effect of the first list above, "SHORT, EXPLAIN",
           is to enable the output of the short error message
           and the explanatory text corresponding to it.

           The effect of the second list is to enable the output
           of the short and long messages.

           The effect of the third list is to enable the output of
           all of the error messages (short, long, explanation
           of the short message, and traceback).

           The effect of the fourth list is to disable output of
           all of the messages.

           The effect of the fifth list is to disable output of
           all of the messages.  The reason for this is that
           the words in the list are responded to in order,
           from left to right, and "NONE" is the last word.

           If any words other than SHORT, LONG, EXPLAIN, ALL,
           DEFAULT, TRACEBACK or NONE appear in list, those words
           that are recognized are responded to.  The words
           that are not recognized are diagnosed as
           erroneous, and error messages are generated
           for each such unrecognized word.

           The length of list is caller-defined, but only
           the first 100 characters of list will be saved
           for later retrieval.

           Only the first 10 items in the list are used;
           the rest are ignored.

-Detailed_Output

   list    is a list of error message items.  The value of
           list is that set by the last call to this routine
           using the "SET" option.  See "Detailed Input"
           for a description of the possible values and
           meanings of list.

           The initial value returned is "DEFAULT".

           Only the first 100 characters of list are saved
           when the list is set; any additional characters
           are truncated.  Therefore, the first 100
           characters, at most, of the saved value of list
           will be returned.

-Parameters

   None.

-Exceptions

   1) If the input argument op does not indicate a valid operation,
      the error SPICE(INVALIDOPERATION) will be signaled.
      
   2) If the input argument list does not indicate a valid list of
      error message types, the error SPICE(INVALIDLISTITEM) will be
      signaled.
      
   3) The error SPICE(EMPTYSTRING) is signalled if the input
      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 string
      pointer is null.
 
   5) The user must pass a value indicating the length of the output
      string, when list is an output.  If this value is not at least 2, 
      the error SPICE(STRINGTOOSHORT) is signaled.

   Also, this routine is part of the CSPICE error
   handling mechanism.

-Files

   None.

-Particulars

   Please read the "required reading"!

   This routine is intended to be used in conjunction with
   errdev_c, which selects the default output device to which
   the error messages selected by this routine will be
   output.

   Additionally, the error response action must be
   something other than "IGNORE" if the error messages
   are to be output.  Possible choices of the error
   response action are "RETURN", "REPORT", "ABORT", "DEFAULT", and
   "IGNORE".  Use erract_c to set the error response action.


   Only the first 100 characters of list are saved.

   The default set of error messages that are output is the
   set specified by "DEFAULT"; i.e., all of them, including
   the "default" message.


-Examples

   1.  In this example, we select as the output device
       the file, SPUD.DAT, and then select the error
       messages to be output.  We choose the short
       error message and the traceback.  Since a
       different set of messages may have been selected
       previously, we clear the old setting by putting
       the word, "NONE", at the beginning of the list.

          /.
          Set the error output device to SPUD.DAT:
          ./
          errdev_c (  "SET", lenout, "SPUD.DAT" );

          /.
          Choose error messages:
          ./
          errprt_c (  "SET", lenout, "NONE, SHORT, TRACEBACK" );


   2.  In this example we are retrieving the error message list.

          /.
          Declare the output string and its size.
          ./

         #define     LENOUT  50

         SpiceChar   list[ LENOUT ];

         errdev_c ( "GET", LENOUT, list );


-Restrictions

   The device to which the selected error messages will
   be written must be selected via errdev_c; otherwise,
   messages will be written to the initial default device.

   Only the first 100 characters of list are saved.

-Literature_References

   None.

-Author_and_Institution

   N.J. Bachman    (JPL)

-Version

   -CSPICE Version 1.3.0, 24-JUN-2003 (NJB)

      Bug fix:  case of invalid operation keyword is now 
      diagnosed, as per the Exceptions section of the header.

   -CSPICE Version 2.0.0, 09-FEB-1998 (NJB) (EDW)

      Input argument op was changed to type ConstSpiceChar *.

      Re-implemented routine without dynamically allocated, temporary 
      strings. 
      
      Corrected errors in examples in which the call sequence
      was incorrect.

   -CSPICE Version 1.0.0, 25-OCT-1997   (EDW)

-Index_Entries

   get/set error output items

-&
*/

{ /* Begin errprt_c */


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

   chkin_c ( "errprt_c" );


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

   if ( eqstr_c ( op, "SET") )
   {

      /*
      Operation is SET. The argument "list" will be an input string.
      Check "list" as well.
      */
      CHKFSTR ( CHK_STANDARD, "errprt_c", list );


      errprt_( ( char * ) op,
               ( char * ) list,
               ( ftnlen ) strlen(op),
               ( ftnlen ) strlen(list) );
   }

   else if ( eqstr_c (op, "GET" ) )
   {

      /*
      Operation is GET.  "list" will be an output string. 
      
      Make sure the output string has at least enough room for one 
      output character and a null terminator.  Also check for a null 
      pointer.
      */
      CHKOSTR ( CHK_STANDARD, "errprt_c", list, lenout );
        
      /*
      After the routine call, create a C string from the
      Fortran output string.
      */
      errprt_( ( char * ) op,
               ( char * ) list,
               ( ftnlen ) strlen(op),
               ( ftnlen ) lenout-1     );


      F2C_ConvertStr( lenout, list );
   }

   else
   {
      setmsg_c ( "Input argument op had value: # "
                 "Valid choices are GET or SET."   );   
      errch_c  ( "#",  op                          );
      sigerr_c ( "SPICE(INVALIDOPERATION)"         );
      chkout_c ( "errprt_c"                        );
      return;
   }


   chkout_c ( "errprt_c" );
   

} /* End errprt_c */
Пример #17
0
   void qcktrc_c ( SpiceInt     tracelen,
                   SpiceChar  * trace    )

/*

-Brief_I/O
 
   VARIABLE  I/O  DESCRIPTION 
   --------  ---  -------------------------------------------------- 
   tracelen   I   Maximum length of output traceback string.
   trace      O   A traceback string. 
   SPICE_ERROR_MAXMOD   
              P   Maximum traceback module count.
   SPICE_ERROR_MODLEN 
              P   Maximum module name length. 
   SPICE_ERROR_TRCLEN
              P   Maximum length of output traceback string.

-Detailed_Input
 
   None. 
 
-Detailed_Output
 
   trace          is a list of module names, delimited by the string, 
                  " --> ".  An example would be
 
                     "SPUD --> SPAM --> FOOBAR". 
 
                  The maximum length of the returned string is given
                  by the parameter SPICE_ERROR_TRCLEN. The value of this
                  parameter includes room for the terminating null.

                  In general, the meaning of the trace is as follows:
 
                  The first name in the list is the name of the first
                  module to check in (that hasn't yet checked out). The
                  last name is the name of the module at the end of the
                  call chain; this is the last module that checked in.
 
                  The meaning of the traceback depends on the state 
                  of the error handling mechanism.  There are two 
                  cases: 
 
                     1)  In RETURN mode, when an error is signaled, the
                         traceback at that point is saved. trcdep_c,
                         trcnam_c, and qcktrc_c return values
                         pertaining to the saved traceback.
 
                     2)  In all other modes, the traceback represents
                         the CURRENT call chain. trcdep_c, trcnam_c,
                         and qcktrc_c return values pertaining to the
                         current trace representation.
 
                  Any module names exceeding SPICE_ERROR_MODLEN
                  characters in length are truncated on the right.
 
-Parameters
 
   The following parameters are declared in the header file SpiceErr.h:


   SPICE_ERROR_MAXMOD    is the maximum number of module names that can
                         be accommodated in the SPICE trace stack; this
                         is the maximum number of names that can appear
                         in the output traceback.

   SPICE_ERROR_MODLEN    is the maximum module name length that can be
                         accommodated by this routine. 

   SPICE_ERROR_TRCLEN    is the maximum length of the string returned
                         by this routine. The value of this parameter
                         includes room for the terminating null.
 
-Exceptions
 
   1)  If the output string pointer is null, the error SPICE(NULLPOINTER)
       will be signaled.


   2)  If the output string has length less than 2 characters, the error
       SPICE(STRINGTOOSHORT) will be signaled.
 
-Files
 
   None. 
 
-Particulars
 
   This routine is part of the CSPICE error handling mechanism. 
 
-Examples
 
   1) Deliberately generate a SPICE error to demonstrate use of 
      this routine together with trcnam_c. We'll attempt to look up 
      a state vector via spkezr_c without first having loaded any
      SPK files.


      Example code begins here.
 

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

         int main()
         {
            /.
            Local constants 
            ./
            #define ACTION          "RETURN"

            /.
            Local variables 
            ./   
            SpiceChar             * abcorr;
            SpiceChar               trace  [ SPICE_ERROR_TRCLEN ];
            SpiceChar             * obsrvr;
            SpiceChar             * frame;
            SpiceChar             * target;

            SpiceDouble             et;
            SpiceDouble             lt;
            SpiceDouble             state [6];

            /.
            Set error handling action to RETURN so that this program
            won't terminate when a SPICE error is signaled. Note that
            the input string length argument is unused for a "SET"
            operation.
            ./
            erract_c ( "SET", 0, ACTION );

            /.
            Generate a SPICE error: call spkezr_c without first having
            loaded an SPK file. 
            ./ 
            et     = 0.0;
            target = "Moon";
            obsrvr = "Earth";
            frame  = "J2000";
            abcorr = "NONE";

            spkezr_c ( target, et, frame, abcorr, obsrvr, state, &lt );

            if ( failed_c() ) 
            {
               /.
               An error has been signaled. Fetch and display
               the traceback.
               ./
               qcktrc_c ( SPICE_ERROR_TRCLEN, trace );

               printf ( "Traceback: \n%s\n", trace );
               /.
               Reset the error status so that CSPICE can resume normal
               operation. 
               ./
               reset_c();
            }

            return ( 0 );
         }

      When this program was executed on a PC/Linux/gcc platform, the
      output (which has been reformatted to fit in the available 
      space in this header) was:


         ====================================================================
         ============

         Toolkit version: N0065

         SPICE(NOLOADEDFILES) --

         At least one SPK file needs to be loaded by SPKLEF before beginning 
         a search.

         A traceback follows.  The name of the highest level module is first.
         spkezr_c --> SPKEZR --> SPKEZ --> SPKGEO --> SPKSFS

         ====================================================================
         ============
         Traceback:
         spkezr_c --> SPKEZR --> SPKEZ --> SPKGEO --> SPKSFS


-Restrictions
 
   1) It is assumed no module names exceed SPICE_ERROR_MODLEN
      characters in length. 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman    (JPL) 
   K.R. Gehringer  (JPL) 
 
-Version
 
   -CSPICE Version 1.0.0, 05-NOV-2013 (NJB) (KRG)

-Index_Entries
 
   get quick traceback 
 
-&
*/

{ /* Begin qcktrc_c */

 
   /*
   This routine does not check in unless an input error occurs.
   */


   /* 
   Make sure the output string has at least enough room for one output
   character and a null terminator. Also check for a null pointer.

   We don't use the usual CHKOSTR macro here because we must reset
   the error status before signaling an error.
   */
   if ( trace == NULL )
   {
      reset_c  ();

      chkin_c  ( "qcktrc_c"                                   );
      setmsg_c ( "The output string pointer 'trace' is null." );
      sigerr_c ( "SPICE(NULLPOINTER)"                         );
      chkout_c ( "qcktrc_c"                                   );
      return;
   }

   if ( tracelen < 2 )
   {
      reset_c  ();

      chkin_c  ( "qcktrc_c"                                     );
      setmsg_c ( "The output string 'trace' has length #; the "
                 "minimum allowed length is 2 characters."      );
      errint_c ( "#",  tracelen                                 );
      sigerr_c ( "SPICE(STRINGTOOSHORT)"                        );
      chkout_c ( "qcktrc_c"                                     );
      return;
   }


   /*
   Fetch the traceback. 
   */
   qcktrc_ ( ( char       * ) trace,
             ( ftnlen       ) tracelen-1 );

   /*
   Convert the output name string to a null-terminated,
   C style string. 
   */
   F2C_ConvertStr ( tracelen, trace );


} /* End qcktrc_c */
Пример #18
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 */
Пример #19
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 */
Пример #20
0
   void npelpt_c ( ConstSpiceDouble      point  [3],
                   ConstSpiceEllipse   * ellips,
                   SpiceDouble           pnear  [3],
                   SpiceDouble         * dist       ) 

/*

-Brief_I/O
 
   Variable  I/O  Description 
   --------  ---  -------------------------------------------------- 
   point      I   Point whose distance to an ellipse is to be found. 
   ellips     I   A CSPICE ellipse. 
   pnear      O   Nearest point on ellipse to input point. 
   dist       O   Distance of input point to ellipse. 
 
-Detailed_Input
 
   ellips         is a CSPICE ellipse that represents an ellipse 
                  in three-dimensional space. 
 
   point          is a point in 3-dimensional space. 
 
-Detailed_Output
 
   pnear          is the nearest point on ellips to point. 
 
   dist           is the distance between point and pnear.  This is 
                  the distance between point and the ellipse. 
 
-Parameters
 
   None. 
 
-Exceptions
 
   1)  Invalid ellipses will be diagnosed by routines called by 
       this routine. 
 
   2)  Ellipses having one or both semi-axis lengths equal to zero 
       are turned away at the door; the error SPICE(DEGENERATECASE) 
       is signalled. 
 
   3)  If the geometric ellipse represented by ellips does not 
       have a unique point nearest to the input point, any point 
       at which the minimum distance is attained may be returned 
       in pnear. 
 
-Files
 
   None. 
 
-Particulars
 
   Given an ellipse and a point in 3-dimensional space, if the 
   orthogonal projection of the point onto the plane of the ellipse 
   is on or outside of the ellipse, then there is a unique point on 
   the ellipse closest to the original point.  This routine finds 
   that nearest point on the ellipse.  If the projection falls inside 
   the ellipse, there may be multiple points on the ellipse that are 
   at the minimum distance from the original point.  In this case, 
   one such closest point will be returned. 
 
   This routine returns a distance, rather than an altitude, in 
   contrast to the CSPICE routine nearpt_c.  Because our ellipse is 
   situated in 3-space and not 2-space, the input point is not 
   `inside' or `outside' the ellipse, so the notion of altitude does 
   not apply to the problem solved by this routine.  In the case of 
   nearpt_c, the input point is on, inside, or outside the ellipsoid, 
   so it makes sense to speak of its altitude. 
 
-Examples
 
   1)  For planetary rings that can be modelled as flat disks with 
       elliptical outer boundaries, the distance of a point in 
       space from a ring's outer boundary can be computed using this 
       routine.  Suppose center, smajor, and sminor are the center, 
       semi-major axis, and semi-minor axis of the ring's boundary. 
       Suppose also that scpos is the position of a spacecraft. 
       scpos, center, smajor, and sminor must all be expressed in 
       the same coordinate system.  We can find the distance from 
       the spacecraft to the ring using the code fragment 
 
          #include "SpiceUsr.h"
               .
               .
               .
          /.
          Make a CSPICE ellipse representing the ring, 
          then use npelpt_c to find the distance between 
          the spacecraft position and RING. 
          ./
          cgv2el_c ( center, smajor, sminor,  ring ); 
          npelpt_c ( scpos,  ring,   pnear,  &dist );
           
 
 
   2)  The problem of finding the distance of a line from a tri-axial 
       ellipsoid can be reduced to the problem of finding the 
       distance between the same line and an ellipse; this problem in 
       turn can be reduced to the problem of finding the distance 
       between an ellipse and a point.  The routine npedln_c carries 
       out this process and uses npelpt_c to find the ellipse-to-point 
       distance. 
 
 
-Restrictions
 
   None. 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman   (JPL) 
 
-Version
 
   -CSPICE Version 1.0.0, 02-SEP-1999 (NJB)

-Index_Entries
 
   nearest point on ellipse to point 
 
-&
*/

{ /* Begin npelpt_c */


   /*
   Local variables
   */

   SpiceDouble             center [3];
   SpiceDouble             majlen;
   SpiceDouble             minlen;
   SpiceDouble             rotate [3][3];
   SpiceDouble             scale;
   SpiceDouble             smajor [3];
   SpiceDouble             sminor [3];
   SpiceDouble             tmppnt [3];
   SpiceDouble             prjpnt [3];


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

 
   /*
   Here's an overview of our solution:

      Let ELPL be the plane containing the ELLIPS, and let PRJ be
      the orthogonal projection of the POINT onto ELPL.  Let X be
      any point in the plane ELPL.  According to the Pythagorean
      Theorem,

                         2                       2                  2
         || POINT - X ||    =   || POINT - PRJ ||   +  || PRJ - X ||.

      Then if we can find a point X on ELLIPS that minimizes the
      rightmost term, that point X is the closest point on the
      ellipse to POINT.

      So, we find the projection PRJ, and then solve the problem of
      finding the closest point on ELLIPS to PRJ.  To solve this
      problem, we find a triaxial ellipsoid whose intersection with
      the plane ELPL is precisely ELLIPS, and two of whose axes lie
      in the plane ELPL.  The closest point on ELLIPS to PRJ is also
      the closest point on the ellipsoid to ELLIPS.  But we have the
      SPICELIB routine NEARPT on hand to find the closest point on an
      ellipsoid to a specified point, so we've reduced our problem to
      a solved problem.

      There is a subtle point to worry about here:  if PRJ is outside
      of ELLIPS (PRJ is in the same plane as ELLIPS, so `outside'
      does make sense here), then the closest point on ELLIPS to PRJ
      coincides with the closest point on the ellipsoid to PRJ,
      regardless of how we choose the z-semi-axis length of the
      ellipsoid.  But the correspondence may be lost if PRJ is inside
      the ellipse, if we don't choose the z-semi-axis length
      correctly.

      Though it takes some thought to verify this (and we won't prove
      it here), making the z-semi-axis of the ellipsoid longer than
      the other two semi-axes is sufficient to maintain the
      coincidence of the closest point on the ellipsoid to PRJPNT and
      the closest point on the ellipse to PRJPNT.
   */


   /*
   Find the ellipse's center and semi-axes.
   */
   el2cgv_c ( ellips, center, smajor, sminor );
 
 
   /*
   Find the lengths of the semi-axes, and scale the vectors to try
   to prevent arithmetic unpleasantness.  Degenerate ellipses are
   turned away at the door.
   */
   
   minlen = vnorm_c (sminor);
   majlen = vnorm_c (smajor);

   if (   MinVal ( majlen, minlen )  ==  0.0  )  
   {
      setmsg_c ( "Ellipse semi-axis lengths: # #." );
      errdp_c  ( "#", majlen                       );
      errdp_c  ( "#", minlen                       );
      sigerr_c ( "SPICE(DEGENERATECASE)"           );
      chkout_c ( "npelpt_c"                        );
      return;  
   }
 

   scale = 1.0 / majlen;

   vscl_c ( scale, smajor, smajor );
   vscl_c ( scale, sminor, sminor );
 
 
   /*
   Translate ellipse and point so that the ellipse is centered at
   the origin.  Scale the point's coordinates to maintain the
   correct relative position to the scaled ellipse.
   */
   vsub_c ( point, center, tmppnt );
   vscl_c ( scale, tmppnt, tmppnt );
 
   
   /*
   We want to reduce the problem to a two-dimensional one.  We'll
   work in a coordinate system whose x- and y- axes are aligned with
   the semi-major and semi-minor axes of the input ellipse.  The
   z-axis is picked to give us a right-handed system.  We find the
   matrix that transforms coordinates to our new system using twovec_c.
   */
   twovec_c ( smajor, 1, sminor, 2, rotate );
 
 
   /*
   Apply the coordinate transformation to our scaled input point.
   */
   mxv_c ( rotate, tmppnt, tmppnt );
 
 
   /*
   We must find the distance between the orthogonal projection of
   tmppnt onto the x-y plane and the ellipse.  The projection is
   just

      ( TMPPNT[0], TMPPNT[1], 0 );

   we'll call this projection prjpnt.
   */

   vpack_c ( tmppnt[0],  tmppnt[1],  0.0,  prjpnt );
   
   
   /*
   Now we're ready to find the distance between and a triaxial
   ellipsoid whose intersection with the x-y plane is the ellipse
   and whose third semi-axis lies on the z-axis.

   Because we've scaled the ellipse's axes so as to give the longer
   axis length 1, a length of 2.0 suffices for the ellipsoid's
   z-semi-axis.

   Find the nearest point to prjpnt on the ellipoid, pnear.
   */
   nearpt_c ( prjpnt, 1.0, minlen/majlen, 2.0, pnear, dist );
 
 
   /*
   Scale the near point coordinates back to the original scale.
   */
   vscl_c ( majlen, pnear, pnear );
 
 
   /*
   Apply the required inverse rotation and translation to pnear.          
   Compute the point-to-ellipse distance.
   */
   mtxv_c ( rotate, pnear,  pnear );
   vadd_c ( pnear,  center, pnear );
 
   *dist = vdist_c ( pnear, point );
 

   chkout_c ( "npelpt_c" );

} /* End npelpt_c */
Пример #21
0
   void nplnpt_c ( ConstSpiceDouble    linpt  [3],
                   ConstSpiceDouble    lindir [3],
                   ConstSpiceDouble    point  [3],
                   SpiceDouble         pnear  [3],
                   SpiceDouble       * dist       ) 

/*

-Brief_I/O
 
   Variable  I/O  Description 
   --------  ---  -------------------------------------------------- 
   linpt, 
   lindir     I   Point on a line and the line's direction vector. 
   point      I   A second point. 
   pnear      O   Nearest point on the line to point. 
   dist       O   Distance between point and pnear. 
 
-Detailed_Input
 
   linpt 
   lindir         are, respectively, a point and a direction vector 
                  that define a line in 3-dimensional space.  The 
                  line is the set of points 
 
                     linpt   +   t * lindir 
 
                  where t is any real number. 
 
   point          is a point in 3-dimensional space. 
 
-Detailed_Output
 
   pnear          is the nearest point on the input line to the input 
                  point. 
 
   dist           is the distance between the input line and input 
                  point. 
 
-Parameters
 
   None. 
 
-Exceptions
 
   1)  If the line direction vector lindir is the zero vector, the 
       error SPICE(ZEROVECTOR) is signaled. 
 
-Files
 
   None. 
 
-Particulars
 
   For every line L and point P, there is a unique closest point 
   on L to P.  Call this closest point C.  It is always true that 
   P - C  is perpendicular to L, and the length of P - C is called 
   the "distance" between P and L. 
 
-Examples
 
   1)  Suppose a line passes through the point ( 1, 2, 3 ) and 
       has direction vector ( 0, 1, 1 ).  We wish to find the 
       closest point on the line to the point ( -6, 9, 10 ).  We 
       can use the code fragment 
 
          #include "SpiceUsr.h"
               .
               .
               .
          LINPT[0]   =  1.0; 
          LINPT[1]   =  2.0; 
          LINPT[2]   =  3.0; 
 
          LINDIR[0]  =  0.0; 
          LINDIR[1]  =  1.0; 
          LINDIR[2]  =  1.0; 
 
          POINT[0]   = -6.0; 
          POINT[1]   =  9.0; 
          POINT[2]   = 10.0; 
 
          nplnpt_c ( linpt, lindir, point, pnear, &dist );
 
 
       After the call, pnear will take the value 
 
          ( 1., 9., 10. ); 
 
       dist will be 7.0. 
 
-Restrictions
 
   None. 
 
-Literature_References
 
   None. 
 
-Author_and_Institution
 
   N.J. Bachman   (JPL) 
 
-Version
 
   -CSPICE Version 1.0.0, 16-AUG-1999 (NJB)

-Index_Entries
 
   distance between point and line 
   nearest point on line to point 
 
-&
*/

{ /* Begin nplnpt_c */

 
   /*
   Local variables
   */
   SpiceDouble             trans [3];
 


   /*
   We need a real direction vector to work with.
   */
   if (  vzero_c (lindir)  )
   {
      chkin_c  ( "nplnpt_c"                           );
      setmsg_c ( "Direction vector must be non-zero." );
      sigerr_c ( "SPICE(ZEROVECTOR)"                  );
      chkout_c ( "nplnpt_c"                           );
      return;
   }
 
 
   /*
   We translate line and input point so as to put the line through
   the origin.  Then the nearest point on the translated line to the
   translated point TRANS is the projection of TRANS onto the line.
   */
   
   vsub_c  ( point,  linpt,  trans );
   vproj_c ( trans,  lindir, pnear );
   vadd_c  ( pnear,  linpt,  pnear );
 
   *dist = vdist_c ( pnear,  point );


} /* End nplnpt_c */
Пример #22
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 */