1 /* dskxsi.f -- translated by f2c (version 19980913).
2    You must link the resulting object file with the libraries:
3 	-lf2c -lm   (in that order)
4 */
5 
6 #include "f2c.h"
7 
8 /* Table of constant values */
9 
10 static integer c__1 = 1;
11 
12 /* $Procedure DSKXSI (DSK, ray-surface intercept with source information) */
dskxsi_(logical * pri,char * target,integer * nsurf,integer * srflst,doublereal * et,char * fixref,doublereal * vertex,doublereal * raydir,integer * maxd,integer * maxi,doublereal * xpt,integer * handle,integer * dladsc,doublereal * dskdsc,doublereal * dc,integer * ic,logical * found,ftnlen target_len,ftnlen fixref_len)13 /* Subroutine */ int dskxsi_(logical *pri, char *target, integer *nsurf,
14 	integer *srflst, doublereal *et, char *fixref, doublereal *vertex,
15 	doublereal *raydir, integer *maxd, integer *maxi, doublereal *xpt,
16 	integer *handle, integer *dladsc, doublereal *dskdsc, doublereal *dc,
17 	integer *ic, logical *found, ftnlen target_len, ftnlen fixref_len)
18 {
19     /* Initialized data */
20 
21     static logical first = TRUE_;
22     static char prvfrm[32] = "                                ";
23     static integer prvtcd = 0;
24 
25     /* Builtin functions */
26     integer s_cmp(char *, char *, ftnlen, ftnlen);
27     /* Subroutine */ int s_copy(char *, char *, ftnlen, ftnlen);
28 
29     /* Local variables */
30     extern /* Subroutine */ int zzbods2c_(integer *, char *, integer *,
31 	    logical *, char *, integer *, logical *, ftnlen, ftnlen),
32 	    zzpctrck_(integer *, logical *), zzsbfxri_(integer *, integer *,
33 	    integer *, doublereal *, integer *, doublereal *, doublereal *,
34 	    doublereal *, integer *, integer *, doublereal *, doublereal *,
35 	    integer *, logical *), zzctruin_(integer *), chkin_(char *,
36 	    ftnlen), errch_(char *, char *, ftnlen, ftnlen);
37     extern logical failed_(void);
38     static integer trgcde, fixfid;
39     logical frmfnd, trgfnd;
40     integer fxcent;
41     static integer svtcde, frmctr[2];
42     integer fxtpid, fxclss;
43     static integer trgctr[2];
44     logical newfrm;
45     static char svtnam[36];
46     extern logical return_(void);
47     logical newtrg;
48     static logical svtfnd;
49     logical update;
50     extern /* Subroutine */ int chkout_(char *, ftnlen), setmsg_(char *,
51 	    ftnlen), sigerr_(char *, ftnlen), errint_(char *, integer *,
52 	    ftnlen), namfrm_(char *, integer *, ftnlen), frinfo_(integer *,
53 	    integer *, integer *, integer *, logical *);
54 
55 /* $ Abstract */
56 
57 /*     Compute a ray-surface intercept using data provided by */
58 /*     multiple loaded DSK segments. Return information about */
59 /*     the source of the data defining the surface on which the */
60 /*     intercept was found: DSK handle, DLA and DSK descriptors, */
61 /*     and DSK data type-dependent parameters. */
62 
63 /* $ Disclaimer */
64 
65 /*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
66 /*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
67 /*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
68 /*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
69 /*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
70 /*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
71 /*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
72 /*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
73 /*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
74 /*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */
75 
76 /*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
77 /*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
78 /*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
79 /*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
80 /*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
81 /*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */
82 
83 /*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
84 /*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
85 /*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
86 /*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */
87 
88 /* $ Required_Reading */
89 
90 /*     CK */
91 /*     DSK */
92 /*     FRAMES */
93 /*     PCK */
94 /*     SPK */
95 /*     TIME */
96 
97 /* $ Keywords */
98 
99 /*     GEOMETRY */
100 /*     INTERCEPT */
101 /*     SURFACE */
102 /*     TOPOGRAPHY */
103 
104 /* $ Declarations */
105 
106 /*     File: dsk.inc */
107 
108 
109 /*     Version 1.0.0 05-FEB-2016 (NJB) */
110 
111 /*     Maximum size of surface ID list. */
112 
113 
114 /*     End of include file dsk.inc */
115 
116 
117 /*     File: dsktol.inc */
118 
119 
120 /*     This file contains declarations of tolerance and margin values */
121 /*     used by the DSK subsystem. */
122 
123 /*     It is recommended that the default values defined in this file be */
124 /*     changed only by expert SPICE users. */
125 
126 /*     The values declared in this file are accessible at run time */
127 /*     through the routines */
128 
129 /*        DSKGTL  {DSK, get tolerance value} */
130 /*        DSKSTL  {DSK, set tolerance value} */
131 
132 /*     These are entry points of the routine DSKTOL. */
133 
134 /*        Version 1.0.0 27-FEB-2016 (NJB) */
135 
136 
137 
138 
139 /*     Parameter declarations */
140 /*     ====================== */
141 
142 /*     DSK type 2 plate expansion factor */
143 /*     --------------------------------- */
144 
145 /*     The factor XFRACT is used to slightly expand plates read from DSK */
146 /*     type 2 segments in order to perform ray-plate intercept */
147 /*     computations. */
148 
149 /*     This expansion is performed to prevent rays from passing through */
150 /*     a target object without any intersection being detected. Such */
151 /*     "false miss" conditions can occur due to round-off errors. */
152 
153 /*     Plate expansion is done by computing the difference vectors */
154 /*     between a plate's vertices and the plate's centroid, scaling */
155 /*     those differences by (1 + XFRACT), then producing new vertices by */
156 /*     adding the scaled differences to the centroid. This process */
157 /*     doesn't affect the stored DSK data. */
158 
159 /*     Plate expansion is also performed when surface points are mapped */
160 /*     to plates on which they lie, as is done for illumination angle */
161 /*     computations. */
162 
163 /*     This parameter is user-adjustable. */
164 
165 
166 /*     The keyword for setting or retrieving this factor is */
167 
168 
169 /*     Greedy segment selection factor */
170 /*     ------------------------------- */
171 
172 /*     The factor SGREED is used to slightly expand DSK segment */
173 /*     boundaries in order to select segments to consider for */
174 /*     ray-surface intercept computations. The effect of this factor is */
175 /*     to make the multi-segment intercept algorithm consider all */
176 /*     segments that are sufficiently close to the ray of interest, even */
177 /*     if the ray misses those segments. */
178 
179 /*     This expansion is performed to prevent rays from passing through */
180 /*     a target object without any intersection being detected. Such */
181 /*     "false miss" conditions can occur due to round-off errors. */
182 
183 /*     The exact way this parameter is used is dependent on the */
184 /*     coordinate system of the segment to which it applies, and the DSK */
185 /*     software implementation. This parameter may be changed in a */
186 /*     future version of SPICE. */
187 
188 
189 /*     The keyword for setting or retrieving this factor is */
190 
191 
192 /*     Segment pad margin */
193 /*     ------------------ */
194 
195 /*     The segment pad margin is a scale factor used to determine when a */
196 /*     point resulting from a ray-surface intercept computation, if */
197 /*     outside the segment's boundaries, is close enough to the segment */
198 /*     to be considered a valid result. */
199 
200 /*     This margin is required in order to make DSK segment padding */
201 /*     (surface data extending slightly beyond the segment's coordinate */
202 /*     boundaries) usable: if a ray intersects the pad surface outside */
203 /*     the segment boundaries, the pad is useless if the intercept is */
204 /*     automatically rejected. */
205 
206 /*     However, an excessively large value for this parameter is */
207 /*     detrimental, since a ray-surface intercept solution found "in" a */
208 /*     segment can supersede solutions in segments farther from the */
209 /*     ray's vertex. Solutions found outside of a segment thus can mask */
210 /*     solutions that are closer to the ray's vertex by as much as the */
211 /*     value of this margin, when applied to a segment's boundary */
212 /*     dimensions. */
213 
214 /*     The keyword for setting or retrieving this factor is */
215 
216 
217 /*     Surface-point membership margin */
218 /*     ------------------------------- */
219 
220 /*     The surface-point membership margin limits the distance */
221 /*     between a point and a surface to which the point is */
222 /*     considered to belong. The margin is a scale factor applied */
223 /*     to the size of the segment containing the surface. */
224 
225 /*     This margin is used to map surface points to outward */
226 /*     normal vectors at those points. */
227 
228 /*     If this margin is set to an excessively small value, */
229 /*     routines that make use of the surface-point mapping won't */
230 /*     work properly. */
231 
232 
233 /*     The keyword for setting or retrieving this factor is */
234 
235 
236 /*     Angular rounding margin */
237 /*     ----------------------- */
238 
239 /*     This margin specifies an amount by which angular values */
240 /*     may deviate from their proper ranges without a SPICE error */
241 /*     condition being signaled. */
242 
243 /*     For example, if an input latitude exceeds pi/2 radians by a */
244 /*     positive amount less than this margin, the value is treated as */
245 /*     though it were pi/2 radians. */
246 
247 /*     Units are radians. */
248 
249 
250 /*     This parameter is not user-adjustable. */
251 
252 /*     The keyword for retrieving this parameter is */
253 
254 
255 /*     Longitude alias margin */
256 /*     ---------------------- */
257 
258 /*     This margin specifies an amount by which a longitude */
259 /*     value can be outside a given longitude range without */
260 /*     being considered eligible for transformation by */
261 /*     addition or subtraction of 2*pi radians. */
262 
263 /*     A longitude value, when compared to the endpoints of */
264 /*     a longitude interval, will be considered to be equal */
265 /*     to an endpoint if the value is outside the interval */
266 /*     differs from that endpoint by a magnitude less than */
267 /*     the alias margin. */
268 
269 
270 /*     Units are radians. */
271 
272 
273 /*     This parameter is not user-adjustable. */
274 
275 /*     The keyword for retrieving this parameter is */
276 
277 
278 /*     End of include file dsktol.inc */
279 
280 
281 /*     File: dsksrc.inc */
282 
283 
284 /*     Version 1.0.0 19-FEB-2016 (NJB) */
285 
286 /*     This file declares sizes of certain output array arguments */
287 /*     returned by DSKXSI. These arrays contain information on the */
288 /*     source of surface data on which an intercept was found. */
289 
290 /*     See the include files */
291 
292 /*        dla.inc */
293 /*        dskdsc.inc */
294 
295 /*     for the declarations of DLA and DSK descriptor sizes, */
296 /*     respectively. */
297 
298 /*     Caution: the sizes declared here may be increased */
299 /*     in a future SPICE Toolkit version. These sizes */
300 /*     are correct for the N0066 Toolkit. */
301 
302 
303 
304 /*     Size of double precision source information component: */
305 
306 /*     Size of integer source information component: */
307 
308 
309 /*     The contents of the components are DSK data type-dependent. */
310 
311 /*         Type 2 */
312 /*         ====== */
313 
314 /*                    Integer component        Double Precision component */
315 
316 /*         Element    Contents */
317 /*         -------    --------------------------------------------------- */
318 /*            1       Plate ID                 Unused */
319 
320 
321 
322 /*     End of include file dsksrc.inc */
323 
324 /* $ Abstract */
325 
326 /*     Declare public surface name/ID mapping parameters. */
327 
328 /* $ Disclaimer */
329 
330 /*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
331 /*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
332 /*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
333 /*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
334 /*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
335 /*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
336 /*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
337 /*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
338 /*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
339 /*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */
340 
341 /*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
342 /*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
343 /*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
344 /*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
345 /*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
346 /*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */
347 
348 /*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
349 /*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
350 /*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
351 /*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */
352 
353 /* $ Required_Reading */
354 
355 /*     NAIF_IDS */
356 
357 /* $ Keywords */
358 
359 /*     CONVERSION */
360 /*     NAME */
361 /*     STRING */
362 /*     SURFACE */
363 
364 /* $ Restrictions */
365 
366 /*     None. */
367 
368 /* $ Author_and_Institution */
369 
370 /*     N.J. Bachman      (JPL) */
371 
372 /* $ Literature_References */
373 
374 /*     None. */
375 
376 /* $ Version */
377 
378 /* -    SPICELIB Version 1.0.0, 02-DEC-2015 (NJB) */
379 
380 /* -& */
381 
382 /*     Maximum number of surface name/ID mapping entries: */
383 
384 
385 /*     Maximum length of a surface name string: */
386 
387 
388 /*     End of file srftrn.inc. */
389 
390 /* $ Abstract */
391 
392 /*     This include file defines the dimension of the counter */
393 /*     array used by various SPICE subsystems to uniquely identify */
394 /*     changes in their states. */
395 
396 /* $ Disclaimer */
397 
398 /*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
399 /*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
400 /*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
401 /*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
402 /*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
403 /*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
404 /*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
405 /*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
406 /*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
407 /*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */
408 
409 /*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
410 /*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
411 /*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
412 /*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
413 /*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
414 /*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */
415 
416 /*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
417 /*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
418 /*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
419 /*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */
420 
421 /* $ Parameters */
422 
423 /*     CTRSIZ      is the dimension of the counter array used by */
424 /*                 various SPICE subsystems to uniquely identify */
425 /*                 changes in their states. */
426 
427 /* $ Author_and_Institution */
428 
429 /*     B.V. Semenov    (JPL) */
430 
431 /* $ Literature_References */
432 
433 /*     None. */
434 
435 /* $ Version */
436 
437 /* -    SPICELIB Version 1.0.0, 29-JUL-2013 (BVS) */
438 
439 /* -& */
440 
441 /*     End of include file. */
442 
443 /* $ Brief_I/O */
444 
445 /*     VARIABLE  I/O  DESCRIPTION */
446 /*     --------  ---  -------------------------------------------------- */
447 /*     PRI        I   Data prioritization flag. */
448 /*     TARGET     I   Target body name. */
449 /*     NSURF      I   Number of surface IDs in list. */
450 /*     SRFLST     I   Surface ID list. */
451 /*     ET         I   Epoch, expressed as seconds past J2000 TDB. */
452 /*     FIXREF     I   Name of target body-fixed reference frame. */
453 /*     VERTEX     I   Vertex of ray. */
454 /*     RAYDIR     I   Direction vector of ray. */
455 /*     MAXD       I   Size of DC array. */
456 /*     MAXI       I   Size of IC array. */
457 /*     XPT        O   Intercept point. */
458 /*     HANDLE     O   Handle of segment contributing surface data. */
459 /*     DLADSC     O   DLA descriptor of segment. */
460 /*     DSKDSC     O   DSK descriptor of segment. */
461 /*     DC         O   Double precision component of source info. */
462 /*     IC         O   Integer component of source info. */
463 /*     FOUND      O   Found flag. */
464 /*     DCSIZE     P   Required size of DC array. */
465 /*     ICSIZE     P   Required size of IC array. */
466 
467 /* $ Detailed_Input */
468 
469 /*     PRI        is a logical flag indicating whether to perform */
470 /*                a prioritized or unprioritized DSK segment search. */
471 /*                In an unprioritized search, no segment masks another: */
472 /*                data from all specified segments are used to */
473 /*                define the surface of interest. */
474 
475 /*                The search is unprioritized if and only if PRI */
476 /*                is set to .FALSE. In the N0066 SPICE Toolkit, this */
477 /*                is the only allowed value. */
478 
479 
480 /*     TARGET     is the name of the target body on which a surface */
481 /*                intercept is sought. */
482 
483 
484 /*     NSURF, */
485 /*     SRFLST     are, respectively, a count of surface ID codes in a */
486 /*                list and an array containing the list. Only DSK */
487 /*                segments for the body designated by TARGET and having */
488 /*                surface IDs in this list will be considered in the */
489 /*                intercept computation. If the list is empty, all DSK */
490 /*                segments for TARGET will be considered. */
491 
492 
493 /*     ET         is the epoch of the intersection computation, */
494 /*                expressed as seconds past J2000 TDB. This epoch is */
495 /*                used only for DSK segment selection. Segments used in */
496 /*                the intercept computation must include ET in their */
497 /*                time coverage intervals. */
498 
499 
500 /*     FIXREF     is the name of a body-fixed, body-centered reference */
501 /*                frame associated with the target. The input ray vectors */
502 /*                are specified in this frame, as is the output intercept */
503 /*                point. */
504 
505 /*                The frame designated by FIXREF must have a fixed */
506 /*                orientation relative to the frame of any DSK segment */
507 /*                used in the computation. */
508 
509 
510 /*     VERTEX, */
511 /*     RAYDIR     are, respectively, the vertex and direction vector of */
512 /*                the ray to be used in the intercept computation. */
513 
514 /*                Both the vertex and ray's direction vector must be */
515 /*                represented in the reference frame designated by */
516 /*                FIXREF. The vertex is considered to be an offset from */
517 /*                the target body. */
518 
519 
520 /*     MAXD, */
521 /*     MAXI       are, respectively, the declared sizes of the arrays */
522 /*                DC and IC. MAXD must be at least DCSIZE, while */
523 /*                MAXI must be at least ICSIZE. See the Parameters */
524 /*                section for details. */
525 
526 /* $ Detailed_Output */
527 
528 
529 /*     XPT        is the intercept of the input ray on the surface */
530 /*                specified by the inputs */
531 
532 /*                   PRI */
533 /*                   TARGET */
534 /*                   NSURF */
535 /*                   SRFLST */
536 /*                   ET */
537 
538 /*                if such an intercept exists. If the ray intersects the */
539 /*                surface at multiple points, the one closest to the */
540 /*                ray's vertex is selected. */
541 
542 /*                XPT is defined if and only if FOUND is .TRUE. */
543 
544 /*                Units are km. */
545 
546 
547 /*     HANDLE, */
548 /*     DLADSC, */
549 /*     DSKDSK     are, respectively, the DSK file handle, DLA descriptor, */
550 /*                and DSK descriptor of the DSK file and segment that */
551 /*                contributed the surface data on which the intercept */
552 /*                was found. */
553 
554 /*                These outputs are defined if and only if FOUND is */
555 /*                .TRUE. */
556 
557 /*     DC, */
558 /*     IC         are, respectively, double precision and integer arrays */
559 /*                that may contain additional information associated */
560 /*                with the segment contributing the surface data on */
561 /*                which the intercept was found. The information is */
562 /*                DSK data type-dependent. */
563 
564 /*                   For DSK type 2 segments */
565 
566 /*                      IC(1) is the intercept plate ID. */
567 /*                      DC is unused. */
568 
569 /*                These outputs are defined if and only if FOUND is */
570 /*                .TRUE. */
571 
572 /*                The declared length of DC must be at least DSIZE; */
573 /*                the declared length of IC must be at least ISIZE. */
574 /*                See the Parameter section for details. */
575 
576 
577 /*     FOUND      is a logical flag that is set to .TRUE. if and only if */
578 /*                and intercept was found. */
579 
580 
581 /* $ Parameters */
582 
583 /*     See the include file */
584 
585 /*        dsksrc.inc */
586 
587 /*     for declarations of size parameters */
588 
589 /*        DCSIZE */
590 /*        ICSIZE */
591 
592 /*     for the output arguments */
593 
594 /*        DC */
595 /*        IC */
596 
597 /*     See the include files */
598 
599 /*        dla.inc */
600 /*        dskdsc.inc */
601 
602 /*     for declarations of DLA and DSK descriptor sizes and */
603 /*     documentation of the contents of these descriptors. */
604 
605 /*     See the include file */
606 
607 /*        dsktol.inc */
608 
609 /*     for the values of tolerance parameters used by default by the */
610 /*     ray-surface intercept algorithm. These are discussed in in the */
611 /*     Particulars section below. */
612 
613 /* $ Exceptions */
614 
615 /*     1)  If the input prioritization flag PRI is set to .TRUE., */
616 /*         the error SPICE(BADPRIORITYSPEC) is signaled. */
617 
618 /*     2)  If the input body name TARGET cannot be mapped to an */
619 /*         ID code, the error SPICE(IDCODENOTFOUND) is signaled. */
620 
621 /*     3)  If the input frame name FIXREF cannot be mapped to an */
622 /*         ID code, the error SPICE(IDCODENOTFOUND) is signaled. */
623 
624 /*     4)  If the frame center associated with FIXREF cannot be */
625 /*         retrieved, the error SPICE(NOFRAMEINFO) is signaled. */
626 
627 /*     5)  If the frame center associated with FIXREF is not */
628 /*         the target body, the error SPICE(INVALIDFRAME) is signaled. */
629 
630 /*     6)  If MAXD is less than DCSIZE or MAXI is less than ICSIZE, */
631 /*         the error SPICE(ARRAYTOOSMALL) will be signaled. */
632 
633 /*     7)  If NSURF is less than 0, the error SPICE(INVALIDCOUNT) */
634 /*         is signaled. */
635 
636 /*     8)  Any errors that occur during the intercept computation */
637 /*         will be signaled by routines in the call tree of this */
638 /*         routine. */
639 /* $ Files */
640 
641 /*     Appropriate kernels must be loaded by the calling program before */
642 /*     this routine is called. */
643 
644 /*     The following data are required: */
645 
646 /*        - SPK data: ephemeris data for the positions of the centers */
647 /*          of DSK reference frames relative to the target body are */
648 /*          required if those frames are not centered at the target */
649 /*          body center. */
650 
651 /*          Typically ephemeris data are made available by loading one */
652 /*          or more SPK files via FURNSH. */
653 
654 /*        - DSK data: DSK files containing topographic data for the */
655 /*          target body must be loaded. If a surface list is specified, */
656 /*          data for at least one of the listed surfaces must be loaded. */
657 
658 /*        - Frame data: if a frame definition is required to convert */
659 /*          DSK segment data to the body-fixed frame designated by */
660 /*          FIXREF, the target, that definition must be available in the */
661 /*          kernel pool. Typically the definitions of frames not already */
662 /*          built-in to SPICE are supplied by loading a frame kernel. */
663 
664 /*        - CK data: if the frame to which FIXREF refers is a CK frame, */
665 /*          and if any DSK segments used in the computation have a */
666 /*          different frame, at least one CK file will be needed to */
667 /*          permit transformation of vectors between that frame and both */
668 /*          the J2000 and the target body-fixed frames. */
669 
670 /*        - SCLK data: if a CK file is needed, an associated SCLK */
671 /*          kernel is required to enable conversion between encoded SCLK */
672 /*          (used to time-tag CK data) and barycentric dynamical time */
673 /*          (TDB). */
674 
675 /*     In all cases, kernel data are normally loaded once per program */
676 /*     run, NOT every time this routine is called. */
677 
678 
679 /* $ Particulars */
680 
681 
682 /*     This is the lowest-level public interface for computing */
683 /*     ray-surface intercepts, where the surface is modeled using */
684 /*     topographic data provided by DSK files. The highest-level */
685 /*     interface for this purpose is SINCPT. */
686 
687 /*     In cases where the data source information returned by this */
688 /*     routine are not needed, the routine DSKXV may be more suitable. */
689 
690 /*     This routine works with multiple DSK files. It places no */
691 /*     restrictions on the data types or coordinate systems of the DSK */
692 /*     segments used in the computation. DSK segments using different */
693 /*     reference frames may be used in a single computation. The only */
694 /*     restriction is that any pair of reference frames used directly or */
695 /*     indirectly are related by a constant rotation. */
696 
697 /*     This routine enables calling applications to identify the source */
698 /*     of the data defining the surface on which an intercept was found. */
699 /*     The file, segment, and segment-specific information such as a DSK */
700 /*     type 2 plate ID are returned. */
701 
702 /*     This routine can be used for improved efficiency in situations */
703 /*     in which multiple ray-surface intercepts are to be performed */
704 /*     using a constant ray vertex. */
705 
706 
707 /*     Using DSK data */
708 /*     ============== */
709 
710 /*        DSK loading and unloading */
711 /*        ------------------------- */
712 
713 /*        DSK files providing data used by this routine are loaded by */
714 /*        calling FURNSH and can be unloaded by calling UNLOAD or */
715 /*        KCLEAR. See the documentation of FURNSH for limits on numbers */
716 /*        of loaded DSK files. */
717 
718 /*        For run-time efficiency, it's desirable to avoid frequent */
719 /*        loading and unloading of DSK files. When there is a reason to */
720 /*        use multiple versions of data for a given target body---for */
721 /*        example, if topographic data at varying resolutions are to be */
722 /*        used---the surface list can be used to select DSK data to be */
723 /*        used for a given computation. It is not necessary to unload */
724 /*        the data that are not to be used. This recommendation presumes */
725 /*        that DSKs containing different versions of surface data for a */
726 /*        given body have different surface ID codes. */
727 
728 
729 /*        DSK data priority */
730 /*        ----------------- */
731 
732 /*        A DSK coverage overlap occurs when two segments in loaded DSK */
733 /*        files cover part or all of the same domain---for example, a */
734 /*        given longitude-latitude rectangle---and when the time */
735 /*        intervals of the segments overlap as well. */
736 
737 /*        When DSK data selection is prioritized, in case of a coverage */
738 /*        overlap, if the two competing segments are in different DSK */
739 /*        files, the segment in the DSK file loaded last takes */
740 /*        precedence. If the two segments are in the same file, the */
741 /*        segment located closer to the end of the file takes */
742 /*        precedence. */
743 
744 /*        When DSK data selection is unprioritized, data from competing */
745 /*        segments are combined. For example, if two competing segments */
746 /*        both represent a surface as sets of triangular plates, the */
747 /*        union of those sets of plates is considered to represent the */
748 /*        surface. */
749 
750 /*        Currently only unprioritized data selection is supported. */
751 /*        Because prioritized data selection may be the default behavior */
752 /*        in a later version of the routine, the presence of the PRI */
753 /*        argument is required. */
754 
755 
756 /*        Round-off errors and mitigating algorithms */
757 /*        ------------------------------------------ */
758 
759 /*        When topographic data are used to represent the surface of a */
760 /*        target body, round-off errors can produce some results that */
761 /*        may seem surprising. */
762 
763 /*        Note that, since the surface in question might have mountains, */
764 /*        valleys, and cliffs, the points of intersection found for */
765 /*        nearly identical sets of inputs may be quite far apart from */
766 /*        each other: for example, a ray that hits a mountain side in a */
767 /*        nearly tangent fashion may, on a different host computer, be */
768 /*        found to miss the mountain and hit a valley floor much farther */
769 /*        from the observer, or even miss the target altogether. */
770 
771 /*        Round-off errors can affect segment selection: for example, a */
772 /*        ray that is expected to intersect the target body's surface */
773 /*        near the boundary between two segments might hit either */
774 /*        segment, or neither of them; the result may be */
775 /*        platform-dependent. */
776 
777 /*        A similar situation exists when a surface is modeled by a set */
778 /*        of triangular plates, and the ray is expected to intersect the */
779 /*        surface near a plate boundary. */
780 
781 /*        To avoid having the routine fail to find an intersection when */
782 /*        one clearly should exist, this routine uses two "greedy" */
783 /*        algorithms: */
784 
785 /*           1) If the ray passes sufficiently close to any of the */
786 /*              boundary surfaces of a segment (for example, surfaces of */
787 /*              maximum and minimum longitude or latitude), that segment */
788 /*              is tested for an intersection of the ray with the */
789 /*              surface represented by the segment's data. */
790 
791 /*              This choice prevents all of the segments from being */
792 /*              missed when at least one should be hit, but it could, on */
793 /*              rare occasions, cause an intersection to be found in a */
794 /*              segment other than the one that would be found if higher */
795 /*              precision arithmetic were used. */
796 
797 /*           2) For type 2 segments, which represent surfaces as */
798 /*              sets of triangular plates, each plate is expanded very */
799 /*              slightly before a ray-plate intersection test is */
800 /*              performed. The default plate expansion factor is */
801 
802 /*                 1 + XFRACT */
803 
804 /*              where XFRACT is declared in */
805 
806 /*                 dsktol.inc */
807 
808 /*              For example, given a value for XFRACT of 1.e-10, the */
809 /*              sides of the plate are lengthened by 1/10 of a micron */
810 /*              per km. The expansion keeps the centroid of the plate */
811 /*              fixed. */
812 
813 /*              Plate expansion prevents all plates from being missed */
814 /*              in cases where clearly at least one should be hit. */
815 
816 /*              As with the greedy segment selection algorithm, plate */
817 /*              expansion can occasionally cause an intercept to be */
818 /*              found on a different plate than would be found if higher */
819 /*              precision arithmetic were used. It also can occasionally */
820 /*              cause an intersection to be found when the ray misses */
821 /*              the target by a very small distance. */
822 
823 /* $ Examples */
824 
825 /*     The numerical results shown for these examples may differ across */
826 /*     platforms. The results depend on the SPICE kernels used as */
827 /*     input, the compiler and supporting libraries, and the machine */
828 /*     specific arithmetic implementation. */
829 
830 /*     1)  Compute surface intercepts of rays emanating from a set of */
831 /*         vertices distributed on a longitude-latitude grid. All */
832 /*         vertices are outside the target body, and all rays point */
833 /*         toward the target's center. */
834 
835 /*         Check intercepts against expected values. Indicate the */
836 /*         number of errors, the number of computations, and the */
837 /*         number of intercepts found. */
838 
839 /*        Use the meta-kernel below to load example SPICE kernels. */
840 
841 
842 /*           KPL/MK */
843 
844 /*           File: dskxsi_ex1.tm */
845 
846 /*           This meta-kernel is intended to support operation of SPICE */
847 /*           example programs. The kernels shown here should not be */
848 /*           assumed to contain adequate or correct versions of data */
849 /*           required by SPICE-based user applications. */
850 
851 /*           In order for an application to use this meta-kernel, the */
852 /*           kernels referenced here must be present in the user's */
853 /*           current working directory. */
854 
855 /*           The names and contents of the kernels referenced */
856 /*           by this meta-kernel are as follows: */
857 
858 /*              File name                        Contents */
859 /*              ---------                        -------- */
860 /*              phobos512.bds                    DSK based on */
861 /*                                               Gaskell ICQ Q=512 */
862 /*                                               plate model */
863 /*           \begindata */
864 
865 /*              PATH_SYMBOLS    = 'GEN' */
866 /*              PATH_VALUES     = '/ftp/pub/naif/generic_kernels' */
867 
868 /*              KERNELS_TO_LOAD = ( '$GEN/dsk/phobos/phobos512.bds' ) */
869 
870 /*           \begintext */
871 
872 
873 /*     Example code begins here. */
874 
875 
876 /*              PROGRAM SPEAR */
877 /*              IMPLICIT NONE */
878 /*        C */
879 /*        C     Multi-segment spear program. */
880 /*        C */
881 /*        C     This program expects all loaded DSKs */
882 /*        C     to represent the same body and surface. */
883 /*        C */
884 /*        C        Syntax: spear <meta-kernel> */
885 /*        C */
886 /*        C */
887 /*              INCLUDE 'dla.inc' */
888 /*              INCLUDE 'dsk.inc' */
889 /*              INCLUDE 'dskdsc.inc' */
890 /*              INCLUDE 'dsksrc.inc' */
891 /*              INCLUDE 'srftrn.inc' */
892 /*        C */
893 /*        C     SPICELIB functions */
894 /*        C */
895 /*              DOUBLE PRECISION      RPD */
896 /*              DOUBLE PRECISION      VDIST */
897 
898 /*              LOGICAL               FAILED */
899 /*        C */
900 /*        C     Local parameters */
901 /*        C */
902 /*              DOUBLE PRECISION      DTOL */
903 /*              PARAMETER           ( DTOL   = 1.D-14 ) */
904 
905 /*              INTEGER               BDNMLN */
906 /*              PARAMETER           ( BDNMLN = 36 ) */
907 
908 /*              INTEGER               FILSIZ */
909 /*              PARAMETER           ( FILSIZ = 255 ) */
910 
911 /*              INTEGER               FRNMLN */
912 /*              PARAMETER           ( FRNMLN = 32 ) */
913 
914 /*              INTEGER               TYPLEN */
915 /*              PARAMETER           ( TYPLEN = 4 ) */
916 
917 /*        C */
918 /*        C     Local variables */
919 /*        C */
920 /*              CHARACTER*(FILSIZ)    DSK1 */
921 /*              CHARACTER*(TYPLEN)    FILTYP */
922 /*              CHARACTER*(FRNMLN)    FIXREF */
923 /*              CHARACTER*(FILSIZ)    META */
924 /*              CHARACTER*(FILSIZ)    SOURCE */
925 /*              CHARACTER*(BDNMLN)    TARGET */
926 
927 /*              DOUBLE PRECISION      D */
928 /*              DOUBLE PRECISION      DC     ( DCSIZE ) */
929 /*              DOUBLE PRECISION      DSKDSC ( DSKDSZ ) */
930 /*              DOUBLE PRECISION      ET */
931 /*              DOUBLE PRECISION      RAYDIR ( 3 ) */
932 /*              DOUBLE PRECISION      LAT */
933 /*              DOUBLE PRECISION      LATCRD ( 3 ) */
934 /*              DOUBLE PRECISION      LATSTP */
935 /*              DOUBLE PRECISION      LON */
936 /*              DOUBLE PRECISION      LONSTP */
937 /*              DOUBLE PRECISION      POLMRG */
938 /*              DOUBLE PRECISION      R */
939 /*              DOUBLE PRECISION      RADIUS */
940 /*              DOUBLE PRECISION      VERTEX ( 3 ) */
941 /*              DOUBLE PRECISION      XPT    ( 3 ) */
942 /*              DOUBLE PRECISION      XYZHIT ( 3 ) */
943 
944 /*              INTEGER               BODYID */
945 /*              INTEGER               DLADSC ( DLADSZ ) */
946 /*              INTEGER               DTYPE */
947 /*              INTEGER               FRAMID */
948 /*              INTEGER               HANDLE */
949 /*              INTEGER               IC     ( ICSIZE ) */
950 /*              INTEGER               NCASES */
951 /*              INTEGER               NDERR */
952 /*              INTEGER               NHITS */
953 /*              INTEGER               NLSTEP */
954 /*              INTEGER               NSURF */
955 /*              INTEGER               PLID */
956 /*              INTEGER               SRFLST ( MAXSRF ) */
957 /*              INTEGER               SURFID */
958 
959 /*              LOGICAL               FOUND */
960 
961 
962 /*              CALL CHKIN ( 'SPEAR' ) */
963 /*        C */
964 /*        C     Load kernel. */
965 /*        C */
966 /*              CALL GETCML ( META ) */
967 
968 /*              IF ( META .EQ. ' ' ) THEN */
969 /*                 CALL TOSTDO( 'Syntax: spear <meta-kernel>' ) */
970 /*                 CALL BYEBYE( 'SUCCESS' ) */
971 /*              END IF */
972 /*        C */
973 /*        C     Load kernels. */
974 /*        C */
975 /*              CALL FURNSH ( META ) */
976 /*        C */
977 /*        C     Get a handle for one of the loaded DSKs, */
978 /*        C     then find the first segment and extract */
979 /*        C     the body and surface IDs. */
980 /*        C */
981 /*              CALL KDATA  ( 1,      'DSK',  DSK1, FILTYP, */
982 /*             .              SOURCE, HANDLE, FOUND ) */
983 
984 /*              CALL DLABFS ( HANDLE, DLADSC, FOUND ) */
985 
986 /*              IF ( .NOT. FOUND ) THEN */
987 /*                 CALL SIGERR ( 'SPICE(NOSEGMENT)' ) */
988 /*              END IF */
989 
990 /*              CALL DSKGD ( HANDLE, DLADSC, DSKDSC ) */
991 
992 /*              BODYID = NINT( DSKDSC(CTRIDX) ) */
993 /*              SURFID = NINT( DSKDSC(SRFIDX) ) */
994 /*              FRAMID = NINT( DSKDSC(FRMIDX) ) */
995 
996 /*              CALL BODC2N ( BODYID, TARGET, FOUND ) */
997 
998 /*              IF ( .NOT. FOUND ) THEN */
999 /*                 CALL SETMSG ( 'Cannot map body ID # to a name.' ) */
1000 /*                 CALL ERRINT ( '#',  BODYID                      ) */
1001 /*                 CALL SIGERR ( 'SPICE(BODYNAMENOTFOUND)'         ) */
1002 /*              END IF */
1003 
1004 /*              CALL FRMNAM ( FRAMID, FIXREF ) */
1005 
1006 /*              IF ( FIXREF .EQ. ' ' ) THEN */
1007 /*                 CALL SETMSG ( 'Cannot map frame ID # to a name.' ) */
1008 /*                 CALL ERRINT ( '#',  FRAMID                       ) */
1009 /*                 CALL SIGERR ( 'SPICE(FRAMENAMENOTFOUND)'         ) */
1010 /*              END IF */
1011 
1012 /*        C */
1013 /*        C     Set the magnitude of the ray vertices. Use a large */
1014 /*        C     number to ensure the vertices are outside of */
1015 /*        C     any realistic target. */
1016 /*        C */
1017 /*              R = 1.D10 */
1018 
1019 /*        C */
1020 /*        C     Spear the target with rays pointing toward */
1021 /*        C     the origin.  Use a grid of ray vertices */
1022 /*        C     located on a sphere enclosing the target. */
1023 /*        C */
1024 /*        C     The variable POLMRG ("pole margin") can */
1025 /*        C     be set to a small positive value to reduce */
1026 /*        C     the number of intercepts done at the poles. */
1027 /*        C     This may speed up the computation for */
1028 /*        C     the multi-segment case, since rays parallel */
1029 /*        C     to the Z axis will cause all segments converging */
1030 /*        C     at the pole of interest to be tested for an */
1031 /*        C     intersection. */
1032 /*        C */
1033 /*              POLMRG = 5.D-1 */
1034 /*              LATSTP = 1.D0 */
1035 /*              LONSTP = 2.D0 */
1036 
1037 /*              NCASES = 0 */
1038 /*              NHITS  = 0 */
1039 /*              NDERR  = 0 */
1040 
1041 /*              LON    = -180.D0 */
1042 /*              LAT    = 90.D0 */
1043 /*              NLSTEP = 0 */
1044 
1045 
1046 /*              WRITE (*,*) 'Computing intercepts...' */
1047 
1048 /*              DO WHILE ( LON .LT. 180.D0 ) */
1049 
1050 /*                 DO WHILE ( NLSTEP .LE. 180  ) */
1051 
1052 /*                    IF ( LON .EQ. -180.D0 ) THEN */
1053 
1054 /*                       LAT = 90.D0 - NLSTEP*LATSTP */
1055 
1056 /*                    ELSE */
1057 
1058 /*                       IF ( NLSTEP .EQ. 0 ) THEN */
1059 
1060 /*                          LAT =  90.D0 - POLMRG */
1061 
1062 /*                       ELSE IF ( NLSTEP .EQ. 180 ) THEN */
1063 
1064 /*                          LAT = -90.D0 + POLMRG */
1065 
1066 /*                       ELSE */
1067 
1068 /*                          LAT = 90.D0 - NLSTEP*LATSTP */
1069 
1070 /*                       END IF */
1071 
1072 /*                    END IF */
1073 
1074 /*                    NCASES = NCASES + 1 */
1075 
1076 /*                    CALL LATREC ( R, LON*RPD(), LAT*RPD(), VERTEX ) */
1077 /*                    CALL VMINUS ( VERTEX, RAYDIR ) */
1078 
1079 /*                    NSURF     = 1 */
1080 /*                    SRFLST(1) = SURFID */
1081 
1082 /*                    CALL DSKXSI ( .FALSE., TARGET, NSURF,  SRFLST, */
1083 /*             .                    ET,      FIXREF, VERTEX, RAYDIR, */
1084 /*             .                    DCSIZE,  ICSIZE, XPT,    HANDLE, */
1085 /*             .                    DLADSC, DSKDSC,  DC,     IC, */
1086 /*             .                    FOUND                           ) */
1087 
1088 /*                    IF ( .NOT. FAILED() .AND. FOUND ) THEN */
1089 /*        C */
1090 /*        C              Record that a new intercept was found. */
1091 /*        C */
1092 /*                       NHITS = NHITS + 1 */
1093 /*        C */
1094 /*        C              Compute the latitude and longitude of */
1095 /*        C              the intercept. Make sure these agree */
1096 /*        C              well with those of the vertex. */
1097 /*        C */
1098 /*                       CALL RECLAT ( XPT,       LATCRD(1), */
1099 /*             .                       LATCRD(2), LATCRD(3) ) */
1100 
1101 /*                       RADIUS = LATCRD(1) */
1102 
1103 /*                       CALL LATREC ( RADIUS,   LON*RPD(), */
1104 /*             .                       LAT*RPD(), XYZHIT    ) */
1105 
1106 /*                       D = VDIST ( XPT, XYZHIT ) */
1107 
1108 /*                       IF ( D/R .GT. DTOL ) THEN */
1109 /*        C */
1110 /*        C                 Get the intercept segment's plate ID if */
1111 /*        C                 applicable. */
1112 /*        C */
1113 /*                          DTYPE = NINT( DSKDSC(TYPIDX) ) */
1114 
1115 /*                          WRITE (*,*) '======================' */
1116 /*                          WRITE (*,*) 'LON, LAT       = ', LON, LAT */
1117 /*                          WRITE (*,*) 'Bad intercept' */
1118 /*                          WRITE (*,*) 'Distance error = ', D */
1119 /*                          WRITE (*,*) 'XPT            = ', XPT */
1120 /*                          WRITE (*,*) 'XYZHIT         = ', XYZHIT */
1121 
1122 /*                          IF ( DTYPE .EQ. 2 ) THEN */
1123 /*                             PLID = IC(1) */
1124 /*                             WRITE (*,*) 'Plate ID      = ', PLID */
1125 /*                          END IF */
1126 
1127 /*                          NDERR = NDERR + 1 */
1128 
1129 /*                       END IF */
1130 
1131 /*                    ELSE */
1132 /*        C */
1133 /*        C              Missing the target entirely is a fatal error. */
1134 /*        C */
1135 /*                       WRITE (*,*) '======================' */
1136 /*                       WRITE (*,*) 'LON, LAT = ', LON, LAT */
1137 /*                       WRITE (*,*) 'No intercept' */
1138 /*                       WRITE (*,*) 'NCASES = ', NCASES */
1139 /*                       STOP */
1140 
1141 /*                    END IF */
1142 
1143 /*                    NLSTEP = NLSTEP + 1 */
1144 
1145 /*                 END DO */
1146 
1147 /*                 LON    = LON + LONSTP */
1148 /*                 LAT    = 90.D0 */
1149 /*                 NLSTEP = 0 */
1150 
1151 /*              END DO */
1152 
1153 /*              WRITE (*,*) 'Done.' */
1154 /*              WRITE (*,*) ' ' */
1155 /*              WRITE (*,*) 'NCASES = ', NCASES */
1156 /*              WRITE (*,*) 'NHITS  = ', NHITS */
1157 /*              WRITE (*,*) 'NDERR  = ', NDERR */
1158 /*              WRITE (*,*) ' ' */
1159 /*              END */
1160 
1161 
1162 /*     When this program was executed on a PC/Linux/gfortran 64-bit */
1163 /*     platform, the output was: */
1164 
1165 
1166 /*        Computing intercepts... */
1167 /*        Done. */
1168 
1169 /*        NCASES =        32580 */
1170 /*        NHITS  =        32580 */
1171 /*        NDERR  =            0 */
1172 
1173 
1174 /* $ Restrictions */
1175 
1176 /*     1)  The frame designated by FIXREF must have a fixed */
1177 /*         orientation relative to the frame of any DSK segment */
1178 /*         used in the computation. This routine has no */
1179 /*         practical way of ensuring that this condition is met; */
1180 /*         so this responsibility is delegated to the calling */
1181 /*         application. */
1182 
1183 /* $ Literature_References */
1184 
1185 /*     None. */
1186 
1187 /* $ Author_and_Institution */
1188 
1189 /*     N.J. Bachman    (JPL) */
1190 
1191 /* $ Version */
1192 
1193 /* -    SPICELIB Version 1.0.0, 04-APR-2017 (NJB) */
1194 
1195 /*        Original 26-FEB-2016 (NJB) */
1196 
1197 
1198 /* -& */
1199 /* $ Index_Entries */
1200 
1201 /*     dsk ray-surface intercept with source information */
1202 /*     dsk ray-surface intercept with handle and descriptors */
1203 /*     dsk ray-surface intercept with handle and descriptors */
1204 
1205 /* -& */
1206 
1207 /*     SPICELIB functions */
1208 
1209 
1210 /*     Local parameters */
1211 
1212 
1213 /*     Local variables */
1214 
1215 
1216 /*     Saved variables */
1217 
1218 
1219 /*     Initial values */
1220 
1221     if (return_()) {
1222 	return 0;
1223     }
1224     chkin_("DSKXSI", (ftnlen)6);
1225     if (first) {
1226 
1227 /*        Initialize counters. */
1228 
1229 	zzctruin_(trgctr);
1230 	zzctruin_(frmctr);
1231 	if (failed_()) {
1232 	    chkout_("DSKXSI", (ftnlen)6);
1233 	    return 0;
1234 	}
1235     }
1236 
1237 /*     Reject PRI if not set properly. */
1238 
1239     if (*pri) {
1240 	setmsg_("In the N0066 SPICE Toolkit, PRI must be set to .FALSE., ind"
1241 		"icating that an unprioritized search is to be performed.", (
1242 		ftnlen)115);
1243 	sigerr_("SPICE(BADPRIORITYSPEC)", (ftnlen)22);
1244 	chkout_("DSKXSI", (ftnlen)6);
1245 	return 0;
1246     }
1247 
1248 /*     Reject NSURF if not set properly. Zero is a valid value. */
1249 
1250     if (*nsurf < 0) {
1251 	setmsg_("The surface count NSURF must be non-negative but was #.", (
1252 		ftnlen)55);
1253 	errint_("#", nsurf, (ftnlen)1);
1254 	sigerr_("SPICE(INVALIDCOUNT)", (ftnlen)19);
1255 	chkout_("DSKXSI", (ftnlen)6);
1256 	return 0;
1257     }
1258 
1259 /*     Check output array sizes. */
1260 
1261     if (*maxd < 1 || *maxi < 1) {
1262 	setmsg_("Output array size MAXD must be at least #; output array siz"
1263 		"e MAXI must be at least #. Actual sizes were # and # respect"
1264 		"ively.", (ftnlen)125);
1265 	errint_("#", &c__1, (ftnlen)1);
1266 	errint_("#", &c__1, (ftnlen)1);
1267 	errint_("#", maxd, (ftnlen)1);
1268 	errint_("#", maxi, (ftnlen)1);
1269 	sigerr_("SPICE(ARRAYTOOSMALL)", (ftnlen)20);
1270 	chkout_("DSKXSI", (ftnlen)6);
1271 	return 0;
1272     }
1273 
1274 /*     Obtain integer codes for the target and reference frame. */
1275 
1276     zzbods2c_(trgctr, svtnam, &svtcde, &svtfnd, target, &trgcde, &trgfnd, (
1277 	    ftnlen)36, target_len);
1278     if (failed_()) {
1279 	chkout_("DSKXSI", (ftnlen)6);
1280 	return 0;
1281     }
1282     if (! trgfnd) {
1283 	setmsg_("The target, '#', is not a recognized name for an ephemeris "
1284 		"object. The cause of this problem may be that you need an up"
1285 		"dated version of the SPICE Toolkit, or that you failed to lo"
1286 		"ad a kernel containing a name-ID mapping for this body.", (
1287 		ftnlen)234);
1288 	errch_("#", target, (ftnlen)1, target_len);
1289 	sigerr_("SPICE(IDCODENOTFOUND)", (ftnlen)21);
1290 	chkout_("DSKXSI", (ftnlen)6);
1291 	return 0;
1292     }
1293     newfrm = s_cmp(fixref, prvfrm, fixref_len, (ftnlen)32) != 0 || first;
1294     newtrg = trgcde != prvtcd || first;
1295 
1296 /*     Get the frame ID if the pool state has changed. The */
1297 /*     first call to ZZPCKTRCK will indicate an update. */
1298 
1299     zzpctrck_(frmctr, &update);
1300     if (update || newfrm || newtrg) {
1301 	namfrm_(fixref, &fixfid, fixref_len);
1302 	if (failed_()) {
1303 	    chkout_("DSKXSI", (ftnlen)6);
1304 	    return 0;
1305 	}
1306 	if (fixfid == 0) {
1307 	    setmsg_("Reference frame # is not recognized by the SPICE frame "
1308 		    "subsystem. Possibly a required frame definition kernel h"
1309 		    "as not been loaded.", (ftnlen)130);
1310 	    errch_("#", fixref, (ftnlen)1, fixref_len);
1311 	    sigerr_("SPICE(IDCODENOTFOUND)", (ftnlen)21);
1312 	    chkout_("DSKXSI", (ftnlen)6);
1313 	    return 0;
1314 	}
1315 
1316 /*        Determine the attributes of the frame designated by FIXREF. */
1317 
1318 	frinfo_(&fixfid, &fxcent, &fxclss, &fxtpid, &frmfnd);
1319 	if (failed_()) {
1320 	    chkout_("DSKXSI", (ftnlen)6);
1321 	    return 0;
1322 	}
1323 	if (! frmfnd) {
1324 	    setmsg_("Attributes for reference frame # could not be obtained "
1325 		    "from the SPICE frame subsystem. Possibly a required fram"
1326 		    "e definition kernel has not been loaded.", (ftnlen)151);
1327 	    errch_("#", fixref, (ftnlen)1, fixref_len);
1328 	    sigerr_("SPICE(NOFRAMEINFO)", (ftnlen)18);
1329 	    chkout_("DSKXSI", (ftnlen)6);
1330 	    return 0;
1331 	}
1332 
1333 /*        Make sure that FIXREF is centered at the target body's center. */
1334 
1335 	if (fxcent != trgcde) {
1336 	    setmsg_("Reference frame # is not centered at the target body #."
1337 		    " The ID code of the frame center is #.", (ftnlen)93);
1338 	    errch_("#", fixref, (ftnlen)1, fixref_len);
1339 	    errch_("#", target, (ftnlen)1, target_len);
1340 	    errint_("#", &fxcent, (ftnlen)1);
1341 	    sigerr_("SPICE(INVALIDFRAME)", (ftnlen)19);
1342 	    chkout_("DSKXSI", (ftnlen)6);
1343 	    return 0;
1344 	}
1345 
1346 /*        We have a valid frame at this point. Save the name. */
1347 
1348 	first = FALSE_;
1349 	s_copy(prvfrm, fixref, (ftnlen)32, fixref_len);
1350 
1351 /*        Update the previous target ID code as well. */
1352 
1353 	prvtcd = trgcde;
1354     }
1355 
1356 /*     TRGCDE and FIXFID are set. */
1357 
1358 
1359 /*     Perform the intercept computation. */
1360 
1361     zzsbfxri_(&trgcde, nsurf, srflst, et, &fixfid, vertex, raydir, xpt,
1362 	    handle, dladsc, dskdsc, dc, ic, found);
1363     chkout_("DSKXSI", (ftnlen)6);
1364     return 0;
1365 } /* dskxsi_ */
1366 
1367