1 /*
2 
3 -Procedure gfsep_c (GF, angular separation search)
4 
5 -Abstract
6 
7    Determine time intervals when the angular separation between
8    the position vectors of two target bodies relative to an observer
9    satisfies a numerical relationship.
10 
11 -Disclaimer
12 
13    THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE
14    CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S.
15    GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE
16    ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE
17    PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS"
18    TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY
19    WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A
20    PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC
21    SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
22    SOFTWARE AND RELATED MATERIALS, HOWEVER USED.
23 
24    IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA
25    BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT
26    LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND,
27    INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS,
28    REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE
29    REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY.
30 
31    RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF
32    THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY
33    CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE
34    ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE.
35 
36 -Required_Reading
37 
38    GF
39    NAIF_IDS
40    SPK
41    TIME
42    WINDOWS
43 
44 -Keywords
45 
46    SEPARATION
47    GEOMETRY
48    SEARCH
49    EVENT
50 
51 */
52 
53    #include <stdlib.h>
54    #include "SpiceUsr.h"
55    #include "SpiceGF.h"
56    #include "SpiceZfc.h"
57    #include "SpiceZmc.h"
58    #include "zzalloc.h"
59 
gfsep_c(ConstSpiceChar * targ1,ConstSpiceChar * shape1,ConstSpiceChar * frame1,ConstSpiceChar * targ2,ConstSpiceChar * shape2,ConstSpiceChar * frame2,ConstSpiceChar * abcorr,ConstSpiceChar * obsrvr,ConstSpiceChar * relate,SpiceDouble refval,SpiceDouble adjust,SpiceDouble step,SpiceInt nintvls,SpiceCell * cnfine,SpiceCell * result)60    void gfsep_c (  ConstSpiceChar     * targ1,
61                    ConstSpiceChar     * shape1,
62                    ConstSpiceChar     * frame1,
63                    ConstSpiceChar     * targ2,
64                    ConstSpiceChar     * shape2,
65                    ConstSpiceChar     * frame2,
66                    ConstSpiceChar     * abcorr,
67                    ConstSpiceChar     * obsrvr,
68                    ConstSpiceChar     * relate,
69                    SpiceDouble          refval,
70                    SpiceDouble          adjust,
71                    SpiceDouble          step,
72                    SpiceInt             nintvls,
73                    SpiceCell          * cnfine,
74                    SpiceCell          * result  )
75 
76 /*
77 
78 -Brief_I/O
79 
80    Variable  I/O  Description
81    --------  ---  --------------------------------------------------
82    SPICE_GF_CNVTOL
83               P   Convergence tolerance.
84    targ1      I   Name of first body
85    shape1     I   Name of shape model describing the first body
86    frame1     I   The body-fixed reference frame of the first body
87    targ2      I   Name of second body
88    shape2     I   Name of the shape model describing the second body
89    frame2     I   The body-fixed reference frame of the second body
90    abcorr     I   Aberration correction flag
91    obsrvr     I   Name of the observing body
92    relate     I   Operator that either looks for an extreme value
93                   (max, min, local, absolute) or compares the
94                   angular separation value and refval
95    refval     I   Reference value
96    adjust     I   Absolute extremum adjustment value
97    step       I   Step size in seconds for finding angular separation
98                   events
99    nintvls    I   Workspace window interval count
100    cnfine    I-O  SPICE window to which the search is restricted
101    result     O   SPICE window containing results
102 
103 -Detailed_Input
104 
105    targ1       the string naming the first body of interest. You can
106                also supply the integer ID code for the object as an
107                integer string.  For example both "MOON" and "301"
108                are legitimate strings that indicate the moon is the
109                target body.
110 
111    shape1      the string naming the geometric model used to represent
112                the shape of the targ1 body. Models supported by this routine:
113 
114                  "SPHERE"        Treat the body as a sphere with radius
115                                  equal to the maximum value of
116                                  BODYnnn_RADII
117 
118                  "POINT"         Treat the body as a point;
119                                  radius has value zero.
120 
121                The 'shape1' string lacks sensitivity to case, leading
122                and trailing blanks.
123 
124    frame1      the string naming the body-fixed reference frame
125                corresponding to targ1. gfsep_c does not currently use
126                this argument's value, its use is reserved for future
127                shape models. The value "NULL" will suffice for
128                "POINT" and "SPHERE" shaped bodies.
129 
130    targ2       the string naming the second body of interest. You can
131                also supply the integer ID code for the object as an
132                integer string.  For example both "MOON" and "301"
133                are legitimate strings that indicate the moon is the
134                target body.
135 
136    shape2      the string naming the geometric model used to represent
137                the shape of the targ2. Models supported by this routine:
138 
139                  "SPHERE"        Treat the body as a sphere with radius
140                                  equal to the maximum value of
141                                  BODYnnn_RADII
142 
143                  "POINT"         Treat the body as a single point;
144                                  radius has value zero.
145 
146                The 'shape2' string lacks sensitivity to case, leading
147                and trailing blanks.
148 
149    frame2      the string naming the body-fixed reference frame
150                corresponding to 'targ2'. gfsep_c does not currently use
151                this argument's value, its use is reserved for future
152                shape models. The value "NULL" will suffice for
153                "POINT" and "SPHERE" shaped bodies.
154 
155    abcorr      the string indicating the aberration corrections to apply
156                to the observer-target position vector to account for
157                one-way light time and stellar aberration.
158 
159                This routine accepts the same aberration corrections as does
160                the SPICE routine SPKEZR. See the header of SPKEZR for a
161                detailed description of the aberration correction options.
162                For convenience, the options are listed below:
163 
164                   "NONE"     Apply no correction.
165 
166                   "LT"       "Reception" case:  correct for
167                              one-way light time using a Newtonian
168                              formulation.
169 
170                   "LT+S"     "Reception" case:  correct for
171                              one-way light time and stellar
172                              aberration using a Newtonian
173                              formulation.
174 
175                   "CN"       "Reception" case:  converged
176                              Newtonian light time correction.
177 
178                   "CN+S"     "Reception" case:  converged
179                              Newtonian light time and stellar
180                              aberration corrections.
181 
182                   "XLT"      "Transmission" case:  correct for
183                              one-way light time using a Newtonian
184                              formulation.
185 
186                   "XLT+S"    "Transmission" case:  correct for
187                              one-way light time and stellar
188                              aberration using a Newtonian
189                              formulation.
190 
191                   "XCN"      "Transmission" case:  converged
192                              Newtonian light time correction.
193 
194                   "XCN+S"    "Transmission" case:  converged
195                              Newtonian light time and stellar
196                              aberration corrections.
197 
198                The abcorr string lacks sensitivity to case, leading
199                and trailing blanks.
200 
201    obsrvr      the string naming the observing body. Optionally, you
202                may supply the ID code of the object as an integer
203                string. For example, both "EARTH" and "399" are
204                legitimate strings to supply to indicate the
205                observer is Earth.
206 
207    relate      the string identifying the relational operator used to
208                define a constraint on the angular separation. The result
209                window found by this routine indicates the time intervals
210                where the constraint is satisfied. Supported values of
211                relate and corresponding meanings are shown below:
212 
213                   ">"      Separation is greater than the reference
214                            value refval.
215 
216                   "="      Separation is equal to the reference
217                            value refval.
218 
219                   "<"      Separation is less than the reference
220                            value refval.
221 
222                  "ABSMAX"  Separation is at an absolute maximum.
223 
224                  "ABSMIN"  Separation is at an absolute  minimum.
225 
226                  "LOCMAX"  Separation is at a local maximum.
227 
228                  "LOCMIN"  Separation is at a local minimum.
229 
230               The caller may indicate that the region of interest
231               is the set of time intervals where the quantity is
232               within a specified angular separation of an absolute extremum.
233               The argument adjust (described below) is used to
234               specify this angular separation.
235 
236               Local extrema are considered to exist only in the
237               interiors of the intervals comprising the confinement
238               window:  a local extremum cannot exist at a boundary
239               point of the confinement window.
240 
241               The relate string lacks sensitivity to case, leading
242               and trailing blanks.
243 
244    refval     the double precision reference value used together with
245               relate argument to define an equality or inequality to be
246               satisfied by the angular separation between the specified target
247               and observer. See the discussion of relate above for
248               further information.
249 
250               The units of refval are radians.
251 
252    adjust     a double precision value used to modify searches for
253               absolute extrema: when relate is set to ABSMAX or ABSMIN and
254               adjust is set to a positive value, GFSEP finds times when the
255               angular separation between the bodies is within adjust radians
256               of the specified extreme value.
257 
258               For relate set to ABSMAX, the result window contains
259               time intervals when the angular separation has
260               values between ABSMAX - adjust and ABSMAX.
261 
262               For relate set to ABSMIN, the result window contains
263               time intervals when the angular separation has
264               values between ABSMIN and ABSMIN + adjust.
265 
266               adjust is not used for searches for local extrema,
267               equality or inequality conditions.
268 
269    step       a double precision value defining the step size to use in
270               the search. step must be short enough for a search using step
271               to locate the time intervals where the specified
272               angular separation function is monotone increasing or
273               decreasing. However, step must not be *too* short, or
274               the search will take an unreasonable amount of time.
275 
276               The choice of step affects the completeness but not
277               the precision of solutions found by this routine; the
278               precision is controlled by the convergence tolerance.
279               See the discussion of the parameter SPICE_GF_CNVTOL for
280               details.
281 
282               'step' has units of TDB seconds.
283 
284    nintvls    an integer value specifying the number of intervals in the
285               the internal workspace array used by this routine. 'nintvls'
286               should be at least as large as the number of intervals
287               within the search region on which the specified observer-target
288               vector coordinate function is monotone increasing or decreasing.
289               It does no harm to pick a value of 'nintvls' larger than the
290               minimum required to execute the specified search, but if chosen
291               too small, the search will fail.
292 
293    cnfine     a double precision SPICE window that confines the time
294               period over which the specified search is conducted.
295               cnfine may consist of a single interval or a collection
296               of intervals.
297 
298               In some cases the confinement window can be used to
299               greatly reduce the time period that must be searched
300               for the desired solution. See the Particulars section
301               below for further discussion.
302 
303               See the Examples section below for a code example
304               that shows how to create a confinement window.
305 
306 -Detailed_Output
307 
308    cnfine     is the input confinement window, updated if necessary
309               so the control area of its data array indicates the
310               window's size and cardinality. The window data are
311               unchanged.
312 
313    result     the SPICE window of intervals, contained within the
314               confinement window cnfine, on which the specified
315               constraint is satisfied.
316 
317               If 'result' is non-empty on input, its contents
318               will be discarded before gfsep_c conducts its
319               search.
320 
321               'result' must be declared and initialized with sufficient
322               size to capture the full set of time intervals
323               within the search region on which the specified constraint
324               is satisfied.
325 
326               If the search is for local extrema, or for absolute
327               extrema with adjust set to zero, then normally each
328               interval of result will be a singleton: the left and
329               right endpoints of each interval will be identical.
330 
331               If no times within the confinement window satisfy the
332               constraint, result will be returned with a
333               cardinality of zero.
334 
335 -Parameters
336 
337    SPICE_GF_CNVTOL
338 
339               is the convergence tolerance used for finding endpoints
340               of the intervals comprising the result window.
341               SPICE_GF_CNVTOL is used to determine when binary searches
342               for roots should terminate: when a root is bracketed
343               within an interval of length SPICE_GF_CNVTOL; the root is
344               considered to have been found.
345 
346               The accuracy, as opposed to precision, of roots found by
347               this routine depends on the accuracy of the input data.
348               In most cases, the accuracy of solutions will be inferior
349               to their precision.
350 
351               SPICE_GF_CNVTOL has the value 1.0e-6. Units are TDB
352               seconds.
353 
354 -Exceptions
355 
356    1)  In order for this routine to produce correct results,
357        the step size must be appropriate for the problem at hand.
358        Step sizes that are too large may cause this routine to miss
359        roots; step sizes that are too small may cause this routine
360        to run unacceptably slowly and in some cases, find spurious
361        roots.
362 
363        This routine does not diagnose invalid step sizes, except
364        that if the step size is non-positive, an error is signaled
365        by a routine in the call tree of this routine.
366 
367    2)  Due to numerical errors, in particular,
368 
369           - Truncation error in time values
370           - Finite tolerance value
371           - Errors in computed geometric quantities
372 
373        it is *normal* for the condition of interest to not always be
374        satisfied near the endpoints of the intervals comprising the
375        result window.
376 
377        The result window may need to be contracted slightly by the
378        caller to achieve desired results. The SPICE window routine
379        wncond_c can be used to contract the result window.
380 
381    3)  If any input string argument pointer is null, the error
382        SPICE(NULLPOINTER) will be signaled.
383 
384    4)  If any input string argument is empty, the error
385        SPICE(EMPTYSTRING) will be signaled.
386 
387    5)  If the workspace interval count 'nintvls' is less than 1, the
388        error SPICE(VALUEOUTOFRANGE) will be signaled.
389 
390    6)  If the required amount of workspace memory cannot be
391        allocated, the error SPICE(MALLOCFAILURE) will be
392        signaled.
393 
394    7)  If an error (typically cell overflow) occurs while performing
395        window arithmetic, the error will be diagnosed by a routine
396        in the call tree of this routine.
397 
398    8)  If the relational operator `relate' is not recognized, an
399        error is signaled by a routine in the call tree of this
400        routine.
401 
402    9)  If the aberration correction specifier contains an
403        unrecognized value, an error is signaled by a routine in the
404        call tree of this routine.
405 
406    10) If 'adjust' is negative, an error is signaled by a routine in
407        the call tree of this routine.
408 
409    11) If either of the input body names, 'targ1', 'targ2' do not map
410        to NAIF ID codes, an error is signaled by a routine in the
411        call tree of this routine.
412 
413    12) If either of the input body shape names, 'shape1', 'shape2',
414        are not recognized by the GF subsystem, an error is signaled
415        by a routine in the call tree of this routine.
416 
417    13) If either of the input body frame names, 'frame1', 'frame2',
418        are not recognized by the frame subsystem, an error is
419        signaled by a routine in the call tree of this routine.
420 
421    14) If either of the input body frames, 'frame1', 'frame2',
422        are not centered on the corresponding body ('frame1' on 'targ1',
423        'frame2' on 'targ2'), an error is signaled by a routine in the
424        call tree of this routine.
425 
426    15) If required ephemerides or other kernel data are not
427        available, an error is signaled by a routine in the call tree
428        of this routine.
429 
430 -Files
431 
432    Appropriate SPK and PCK kernels must be loaded by the
433    calling program before this routine is called.
434 
435    The following data are required:
436 
437       - SPK data: the calling application must load ephemeris data
438         for the targets, observer, and any intermediate objects in
439         a chain connecting the targets and observer that cover the time
440         period specified by the window CNFINE. If aberration
441         corrections are used, the states of target and observer
442         relative to the solar system barycenter must be calculable
443         from the available ephemeris data. Typically ephemeris data
444         are made available by loading one or more SPK files using
445         FURNSH.
446 
447       - PCK data: bodies modeled as triaxial ellipsoids must have
448         semi-axis lengths provided by variables in the kernel pool.
449         Typically these data are made available by loading a text
450         PCK file using FURNSH.
451 
452       - If non-inertial reference frames are used, then PCK
453         files, frame kernels, C-kernels, and SCLK kernels may be
454         needed.
455 
456    Such kernel data are normally loaded once per program
457    run, NOT every time this routine is called.
458 
459 -Particulars
460 
461 
462    This routine provides a simpler, but less flexible interface
463    than does the routine gfevnt_c for conducting searches for
464    angular separation events. Applications that require support for
465    progress reporting, interrupt handling, non-default step or
466    refinement functions, or non-default convergence tolerance should
467    call gfevnt_c rather than this routine.
468 
469    This routine determines a set of one or more time intervals
470    within the confinement window for which the angular separation
471    between the two bodies satisfies some defined relationship.
472    The resulting set of intervals is returned as a SPICE window.
473 
474    Below we discuss in greater detail aspects of this routine's
475    solution process that are relevant to correct and efficient
476    use of this routine in user applications.
477 
478    The Search Process
479    ==================
480 
481    Regardless of the type of constraint selected by the caller, this
482    routine starts the search for solutions by determining the time
483    periods, within the confinement window, over which the specified
484    angular separation function is monotone increasing and monotone
485    decreasing. Each of these time periods is represented by a SPICE window.
486    Having found these windows, all of the angular separation function's
487    local extrema within the confinement window are known. Absolute extrema
488    then can be found very easily.
489 
490    Within any interval of these "monotone" windows, there will be at
491    most one solution of any equality constraint. Since the boundary
492    of the solution set for any inequality constraint is contained in
493    the union of
494 
495       - the set of points where an equality constraint is met
496       - the boundary points of the confinement window
497 
498    the solutions of both equality and inequality constraints can be
499    found easily once the monotone windows have been found.
500 
501 
502    Step Size
503    =========
504 
505    The monotone windows (described above) are found using a two-step
506    search process. Each interval of the confinement window is
507    searched as follows: first, the input step size is used to
508    determine the time separation at which the sign of the rate of
509    change of angular separation (angular separation rate) will be
510    sampled. Starting at the left endpoint of an interval, samples
511    will be taken at each step. If a change of sign is found, a
512    root has been bracketed; at that point, the time at which the
513    angular separation rate is zero can be found by a refinement
514    process, for example, using a binary search.
515 
516    Note that the optimal choice of step size depends on the lengths
517    of the intervals over which the distance function is monotone:
518    the step size should be shorter than the shortest of these
519    intervals (within the confinement window).
520 
521    The optimal step size is *not* necessarily related to the lengths
522    of the intervals comprising the result window. For example, if
523    the shortest monotone interval has length 10 days, and if the
524    shortest result window interval has length 5 minutes, a step size
525    of 9.9 days is still adequate to find all of the intervals in the
526    result window. In situations like this, the technique of using
527    monotone windows yields a dramatic efficiency improvement over a
528    state-based search that simply tests at each step whether the
529    specified constraint is satisfied. The latter type of search can
530    miss solution intervals if the step size is longer than the
531    shortest solution interval.
532 
533    Having some knowledge of the relative geometry of the target and
534    observer can be a valuable aid in picking a reasonable step size.
535    In general, the user can compensate for lack of such knowledge by
536    picking a very short step size; the cost is increased computation
537    time.
538 
539    Note that the step size is not related to the precision with which
540    the endpoints of the intervals of the result window are computed.
541    That precision level is controlled by the convergence tolerance.
542 
543 
544    Convergence Tolerance
545    =====================
546 
547    As described above, the root-finding process used by this routine
548    involves first bracketing roots and then using a search process to
549    locate them.  "Roots" include times when extrema are attained and
550    times when the geometric quantity function is equal to a reference
551    value or adjusted extremum. All endpoints of the intervals comprising
552    the result window are either endpoints of intervals of the confinement
553    window or roots.
554 
555    Once a root has been bracketed, a refinement process is used to
556    narrow down the time interval within which the root must lie.
557    This refinement process terminates when the location of the root
558    has been determined to within an error margin called the
559    "convergence tolerance." The convergence tolerance used by this
560    routine is set via the parameter SPICE_GF_CNVTOL.
561 
562    The value of SPICE_GF_CNVTOL is set to a "tight" value so that the
563    tolerance doesn't limit the accuracy of solutions found by this
564    routine. In general the accuracy of input data will be the limiting
565    factor.
566 
567    The user may change the convergence tolerance from the default
568    SPICE_GF_CNVTOL value by calling the routine gfstol_c, e.g.
569 
570       gfstol_c( tolerance value in seconds )
571 
572    Call gfstol_c prior to calling this routine. All subsequent
573    searches will use the updated tolerance value.
574 
575    Searches over time windows of long duration may require use of
576    larger tolerance values than the default: the tolerance must be
577    large enough so that it, when added to or subtracted from the
578    confinement window's lower and upper bounds, yields distinct time
579    values.
580 
581    Setting the tolerance tighter than SPICE_GF_CNVTOL is unlikely to be
582    useful, since the results are unlikely to be more accurate.
583    Making the tolerance looser will speed up searches somewhat,
584    since a few convergence steps will be omitted. However, in most
585    cases, the step size is likely to have a much greater effect
586    on processing time than would the convergence tolerance.
587 
588 
589    The Confinement Window
590    ======================
591 
592    The simplest use of the confinement window is to specify a time
593    interval within which a solution is sought. However, the
594    confinement window can, in some cases, be used to make searches
595    more efficient. Sometimes it's possible to do an efficient search
596    to reduce the size of the time period over which a relatively
597    slow search of interest must be performed.
598 
599 
600    Negative Angular Separation
601    ===========================
602 
603    For those searches using a SPHERE shape identifier for both
604    target bodies, the angular separation function returns a
605    negative value when the bodies overlap (occult), e.g.
606    a search for an ABSMIN of angular separation in a
607    confinement window covering an occultation event will
608    return the time when the apparent center of the
609    occulting body passes closest to the apparent center of
610    the occulted body.
611 
612 
613    Elongation
614    ===========================
615 
616    The angular separation of two targets as seen from an observer
617    where one of those targets is the sun is known as elongation.
618 
619 -Examples
620 
621 
622    The numerical results shown for these examples may differ across
623    platforms. The results depend on the SPICE kernels used as
624    input, the compiler and supporting libraries, and the machine
625    specific arithmetic implementation.
626 
627       Use the meta-kernel shown below to load the required SPICE
628       kernels.
629 
630          KPL/MK
631 
632          File name: standard.tm
633 
634          This meta-kernel is intended to support operation of SPICE
635          example programs. The kernels shown here should not be
636          assumed to contain adequate or correct versions of data
637          required by SPICE-based user applications.
638 
639          In order for an application to use this meta-kernel, the
640          kernels referenced here must be present in the user's
641          current working directory.
642 
643          The names and contents of the kernels referenced
644          by this meta-kernel are as follows:
645 
646             File name                     Contents
647             ---------                     --------
648             de421.bsp                     Planetary ephemeris
649             pck00009.tpc                  Planet orientation and
650                                           radii
651             naif0009.tls                  Leapseconds
652 
653          \begindata
654 
655             KERNELS_TO_LOAD = ( 'de421.bsp',
656                                 'pck00009.tpc',
657                                 'naif0009.tls'  )
658 
659          \begintext
660 
661    Example(1):
662 
663       Determine the times of local maxima of the angular separation
664       between the moon and earth as observed from the sun from
665       January 1, 2007 UTC to January 1 2008 UTC.
666 
667       #include <stdio.h>
668       #include <stdlib.h>
669       #include <string.h>
670 
671       #include "SpiceUsr.h"
672 
673       #define       MAXWIN    1000
674       #define       TIMFMT    "YYYY-MON-DD HR:MN:SC.###### (TDB) ::TDB ::RND"
675       #define       TIMLEN   41
676 
677       int main( int argc, char **argv )
678          {
679 
680          /.
681          Create the needed windows. Note, one window
682          consists of two values, so the total number
683          of cell values to allocate equals twice
684          the number of windows.
685          ./
686          SPICEDOUBLE_CELL ( result, 2*MAXWIN );
687          SPICEDOUBLE_CELL ( cnfine, 2       );
688 
689          SpiceDouble       begtim;
690          SpiceDouble       endtim;
691          SpiceDouble       step;
692          SpiceDouble       adjust;
693          SpiceDouble       refval;
694          SpiceDouble       beg;
695          SpiceDouble       end;
696 
697          SpiceChar         begstr [ TIMLEN ];
698          SpiceChar         endstr [ TIMLEN ];
699 
700          SpiceChar       * targ1  = "MOON";
701          SpiceChar       * frame1 = "NULL";
702          SpiceChar       * shape1 = "SPHERE";
703 
704          SpiceChar       * targ2  = "EARTH";
705          SpiceChar       * frame2 = "NULL";
706          SpiceChar       * shape2 = "SPHERE";
707 
708          SpiceChar       * abcorr = "NONE";
709          SpiceChar       * relate = "LOCMAX";
710 
711          SpiceChar       * obsrvr = "SUN";
712 
713          SpiceInt          count;
714          SpiceInt          i;
715 
716          /.
717          Load kernels.
718          ./
719          furnsh_c( "standard.tm" );
720 
721          /.
722          Store the time bounds of our search interval in
723          the cnfine confinement window.
724          ./
725          str2et_c( "2007 JAN 01", &begtim );
726          str2et_c( "2008 JAN 01", &endtim );
727 
728          wninsd_c ( begtim, endtim, &cnfine );
729 
730          /.
731          Search using a step size of 6 days (in units of seconds).
732          ./
733          step   = 6.*spd_c();
734          adjust = 0.;
735          refval = 0.;
736 
737          /.
738          List the beginning and ending points in each interval
739          if result contains data.
740          ./
741          gfsep_c ( targ1,
742                   shape1,
743                   frame1,
744                   targ2,
745                   shape2,
746                   frame2,
747                   abcorr,
748                   obsrvr,
749                   relate,
750                   refval,
751                   adjust,
752                   step,
753                   MAXWIN,
754                   &cnfine,
755                   &result );
756 
757          count = wncard_c( &result );
758 
759          /.
760          Display the results.
761          ./
762          if (count == 0 )
763             {
764             printf ( "Result window is empty.\n\n" );
765             }
766          else
767             {
768             for ( i = 0;  i < count;  i++ )
769                {
770 
771                /.
772                Fetch the endpoints of the Ith interval
773                of the result window.
774                ./
775                wnfetd_c ( &result, i, &beg, &end );
776 
777                timout_c ( beg, TIMFMT, TIMLEN, begstr );
778                timout_c ( end, TIMFMT, TIMLEN, endstr );
779 
780                printf ( "Interval %d\n", i + 1);
781                printf ( "Beginning TDB %s \n", begstr );
782                printf ( "Ending TDB    %s \n", endstr );
783 
784                }
785             }
786 
787          kclear_c();
788          return( 0 );
789          }
790 
791       The program's partial output:
792 
793          Interval 1
794          Beginning TDB 2007-JAN-11 11:21:20.213872 (TDB)
795          Ending TDB    2007-JAN-11 11:21:20.213872 (TDB)
796 
797          Interval 2
798          Beginning TDB 2007-JAN-26 01:43:41.029955 (TDB)
799          Ending TDB    2007-JAN-26 01:43:41.029955 (TDB)
800 
801             ...
802 
803          Interval 24
804          Beginning TDB 2007-DEC-17 04:04:46.935442 (TDB)
805          Ending TDB    2007-DEC-17 04:04:46.935442 (TDB)
806 
807          Interval 25
808          Beginning TDB 2007-DEC-31 13:43:52.558897 (TDB)
809          Ending TDB    2007-DEC-31 13:43:52.558897 (TDB)
810 
811    Example(2):
812 
813       Determine the time of local maxima elongation of the
814       Moon as seen from earth for the same time interval
815       as the previous example:
816 
817       Edit the Example(1) program to use the assignments:
818 
819          SpiceChar       * targ1  = "MOON";
820          SpiceChar       * targ2  = "SUN";
821          SpiceChar       * obsrvr = "EARTH";
822 
823       The program's partial output:
824 
825          Interval 1
826          Beginning TDB 2007-JAN-03 14:20:24.618884 (TDB)
827          Ending TDB    2007-JAN-03 14:20:24.618884 (TDB)
828 
829          Interval 2
830          Beginning TDB 2007-FEB-02 06:16:24.101655 (TDB)
831          Ending TDB    2007-FEB-02 06:16:24.101655 (TDB)
832 
833             ...
834 
835          Interval 12
836          Beginning TDB 2007-NOV-24 14:31:04.334590 (TDB)
837          Ending TDB    2007-NOV-24 14:31:04.334590 (TDB)
838 
839          Interval 13
840          Beginning TDB 2007-DEC-24 01:40:12.238389 (TDB)
841          Ending TDB    2007-DEC-24 01:40:12.238389 (TDB)
842 
843 -Restrictions
844 
845    1) The kernel files to be used by this routine must be loaded
846       (normally via the CSPICE routine furnsh_c) before this routine
847       is called.
848 
849    2) This routine has the side effect of re-initializing the
850       angular separation quantity utility package.  Callers may
851       need to re-initialize the package after calling this routine.
852 
853    3) Due to the current logic implemented in zzgfspu, a direct
854       search for zero angular separation of two point targets will
855       always fails, i.e.,
856 
857            'relate' has value "="
858            'refval' has value 0.
859 
860         Use 'relate' values of "ABSMIN" or "LOCMIN" to detect such an event(s).
861 
862 -Literature_References
863 
864    None.
865 
866 -Author_and_Institution
867 
868    N.J. Bachman   (JPL)
869    E.D. Wright    (JPL)
870 
871 -Version
872 
873    -CSPICE Version 1.0.2, 30-JUL-2014 (EDW)
874 
875       Edit to argument I/O 'frame1' and 'frame2' to mention use of
876       "NULL."
877 
878       Edit to header, correct Required Reading entry eliminating ".REQ"
879       suffix.
880 
881    -CSPICE Version 1.0.1, 28-FEB-2013 (NJB) (EDW)
882 
883       Header was updated to discuss use of gfstol_c.
884 
885       Edit to comments to correct search description.
886 
887       Edited argument descriptions. Removed mention of "ELLIPSOID"
888       shape from 'shape1' and 'shape2' as that option is not yet
889       implemented.
890 
891       Typo corrected in 1.0.1 Version description, replaced
892       "gfrr_c" with "gfsep_c."
893 
894       Small text edit for clarity on example code description; full date
895       strings replaced abbreviated versions.
896 
897       Edits to Example section, proper description of "standard.tm"
898       meta kernel.
899 
900       Edits to Exceptions section to improve description of
901       exceptions and error signals.
902 
903    -CSPICE Version 1.0.1, 19-AUG-2009 (EDW)
904 
905       Corrected typo in the VALUEOUTOFRANGE error message. Corrected
906       the routine name in "chkout_c" call, "gfposc_c", with correct
907       name "gfsep_c."
908 
909    -CSPICE Version 1.0.0, 10-FEB-2009 (NJB) (EDW)
910 
911 -Index_Entries
912 
913    GF angular separation search
914 
915 -&
916 */
917 
918    { /* Begin gfsep_c */
919 
920    /*
921    Local variables
922    */
923    doublereal            * work;
924 
925    static SpiceInt         nw = SPICE_GF_NWSEP;
926    SpiceInt                nBytes;
927 
928 
929    /*
930    Participate in error tracing.
931    */
932    if ( return_c() )
933       {
934       return;
935       }
936    chkin_c ( "gfsep_c" );
937 
938 
939    /*
940    Make sure cell data types are d.p.
941    */
942    CELLTYPECHK2 ( CHK_STANDARD, "gfsep_c", SPICE_DP, cnfine, result );
943 
944    /*
945    Initialize the input cells if necessary.
946    */
947    CELLINIT2 ( cnfine, result );
948 
949    /*
950    Check the input strings to make sure each pointer is non-null
951    and each string length is non-zero.
952    */
953    CHKFSTR ( CHK_STANDARD, "gfsep_c", targ1  );
954    CHKFSTR ( CHK_STANDARD, "gfsep_c", shape1 );
955    CHKFSTR ( CHK_STANDARD, "gfsep_c", frame1 );
956    CHKFSTR ( CHK_STANDARD, "gfsep_c", targ2  );
957    CHKFSTR ( CHK_STANDARD, "gfsep_c", shape2 );
958    CHKFSTR ( CHK_STANDARD, "gfsep_c", frame2 );
959    CHKFSTR ( CHK_STANDARD, "gfsep_c", abcorr );
960    CHKFSTR ( CHK_STANDARD, "gfsep_c", obsrvr );
961    CHKFSTR ( CHK_STANDARD, "gfsep_c", relate );
962 
963    /*
964    Check the workspace size; some mallocs have a violent
965    dislike for negative allocation amounts. To be safe,
966    rule out a count of zero intervals as well.
967    */
968 
969    if ( nintvls < 1 )
970       {
971       setmsg_c ( "The specified workspace interval count # was "
972                  "less than the minimum allowed value of one (1)." );
973       errint_c ( "#",  nintvls                              );
974       sigerr_c ( "SPICE(VALUEOUTOFRANGE)"                   );
975       chkout_c ( "gfsep_c"                                 );
976       return;
977       }
978 
979    /*
980    Allocate the workspace. 'nintvls' indicates the maximum number of
981    intervals returned in 'result'. An interval consists of
982    two values.
983    */
984 
985    nintvls = 2 * nintvls;
986 
987    nBytes = ( nintvls + SPICE_CELL_CTRLSZ ) * nw * sizeof(SpiceDouble);
988 
989    work   = (doublereal *) alloc_SpiceMemory( nBytes );
990 
991    if ( !work )
992       {
993       setmsg_c ( "Workspace allocation of # bytes failed due to "
994                  "malloc failure"                               );
995       errint_c ( "#",  nBytes                                   );
996       sigerr_c ( "SPICE(MALLOCFAILED)"                          );
997       chkout_c ( "gfsep_c"                                      );
998       return;
999       }
1000 
1001    /*
1002    Let the f2'd routine do the work.
1003    */
1004 
1005    gfsep_( ( char          * ) targ1,
1006            ( char          * ) shape1,
1007            ( char          * ) frame1,
1008            ( char          * ) targ2,
1009            ( char          * ) shape2,
1010            ( char          * ) frame2,
1011            ( char          * ) abcorr,
1012            ( char          * ) obsrvr,
1013            ( char          * ) relate,
1014            ( doublereal    * ) &refval,
1015            ( doublereal    * ) &adjust,
1016            ( doublereal    * ) &step,
1017            ( doublereal    * ) (cnfine->base),
1018            ( integer       * ) &nintvls,
1019            ( integer       * ) &nw,
1020            ( doublereal    * ) work,
1021            ( doublereal    * ) (result->base),
1022            ( ftnlen          ) strlen(targ1),
1023            ( ftnlen          ) strlen(shape1),
1024            ( ftnlen          ) strlen(frame1),
1025            ( ftnlen          ) strlen(targ2),
1026            ( ftnlen          ) strlen(shape2),
1027            ( ftnlen          ) strlen(frame2),
1028            ( ftnlen          ) strlen(abcorr),
1029            ( ftnlen          ) strlen(obsrvr),
1030            ( ftnlen          ) strlen(relate) );
1031 
1032    /*
1033    De-allocate the workspace.
1034    */
1035    free_SpiceMemory( work );
1036 
1037    /*
1038    Sync the output cell.
1039    */
1040    if ( !failed_c() )
1041       {
1042       zzsynccl_c ( F2C, result ) ;
1043       }
1044 
1045    ALLOC_CHECK;
1046 
1047    chkout_c ( "gfsep_c" );
1048 
1049    } /* End gfsep_c */
1050