1 /* 2 3 -Procedure gfocce_c ( GF, occultation event ) 4 5 -Abstract 6 7 Determine time intervals when an observer sees one target 8 occulted by another. Report progress and handle interrupts 9 if so commanded. 10 11 The surfaces of the target bodies may be represented by triaxial 12 ellipsoids or by topographic data provided by DSK files. 13 14 -Disclaimer 15 16 THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE 17 CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. 18 GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE 19 ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE 20 PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" 21 TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY 22 WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A 23 PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC 24 SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE 25 SOFTWARE AND RELATED MATERIALS, HOWEVER USED. 26 27 IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA 28 BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT 29 LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, 30 INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, 31 REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE 32 REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. 33 34 RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF 35 THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY 36 CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE 37 ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. 38 39 -Required_Reading 40 41 FRAMES 42 GF 43 KERNEL 44 NAIF_IDS 45 SPK 46 TIME 47 WINDOWS 48 49 -Keywords 50 51 EVENT 52 GEOMETRY 53 SEARCH 54 WINDOW 55 56 */ 57 #include <signal.h> 58 #include "SpiceUsr.h" 59 #include "SpiceZmc.h" 60 #include "SpiceZfc.h" 61 #include "SpiceZad.h" 62 63 gfocce_c(ConstSpiceChar * occtyp,ConstSpiceChar * front,ConstSpiceChar * fshape,ConstSpiceChar * fframe,ConstSpiceChar * back,ConstSpiceChar * bshape,ConstSpiceChar * bframe,ConstSpiceChar * abcorr,ConstSpiceChar * obsrvr,SpiceDouble tol,void (* udstep)(SpiceDouble et,SpiceDouble * step),void (* udrefn)(SpiceDouble t1,SpiceDouble t2,SpiceBoolean s1,SpiceBoolean s2,SpiceDouble * t),SpiceBoolean rpt,void (* udrepi)(SpiceCell * cnfine,ConstSpiceChar * srcpre,ConstSpiceChar * srcsuf),void (* udrepu)(SpiceDouble ivbeg,SpiceDouble ivend,SpiceDouble et),void (* udrepf)(void),SpiceBoolean bail,SpiceBoolean (* udbail)(void),SpiceCell * cnfine,SpiceCell * result)64 void gfocce_c ( ConstSpiceChar * occtyp, 65 ConstSpiceChar * front, 66 ConstSpiceChar * fshape, 67 ConstSpiceChar * fframe, 68 ConstSpiceChar * back, 69 ConstSpiceChar * bshape, 70 ConstSpiceChar * bframe, 71 ConstSpiceChar * abcorr, 72 ConstSpiceChar * obsrvr, 73 SpiceDouble tol, 74 75 void ( * udstep ) ( SpiceDouble et, 76 SpiceDouble * step ), 77 78 void ( * udrefn ) ( SpiceDouble t1, 79 SpiceDouble t2, 80 SpiceBoolean s1, 81 SpiceBoolean s2, 82 SpiceDouble * t ), 83 SpiceBoolean rpt, 84 85 void ( * udrepi ) ( SpiceCell * cnfine, 86 ConstSpiceChar * srcpre, 87 ConstSpiceChar * srcsuf ), 88 89 void ( * udrepu ) ( SpiceDouble ivbeg, 90 SpiceDouble ivend, 91 SpiceDouble et ), 92 93 void ( * udrepf ) ( void ), 94 SpiceBoolean bail, 95 SpiceBoolean ( * udbail ) ( void ), 96 SpiceCell * cnfine, 97 SpiceCell * result ) 98 99 /* 100 101 -Brief_I/O 102 103 VARIABLE I/O DESCRIPTION 104 -------- --- -------------------------------------------------- 105 occtyp I Type of occultation. 106 front I Name of body occulting the other. 107 fshape I Type of shape model used for front body. 108 fframe I Body-fixed, body-centered frame for front body. 109 back I Name of body occulted by the other. 110 bshape I Type of shape model used for back body. 111 bframe I Body-fixed, body-centered frame for back body. 112 abcorr I Aberration correction flag. 113 obsrvr I Name of the observing body. 114 tol I Convergence tolerance in seconds. 115 udstep I Name of the routine that returns a time step. 116 udrefn I Name of the routine that computes a refined time. 117 rpt I Progress report flag. 118 udrepi I Function that initializes progress reporting. 119 udrepu I Function that updates the progress report. 120 udrepf I Function that finalizes progress reporting. 121 bail I Logical indicating program interrupt monitoring. 122 udbail I Name of a routine that signals a program interrupt. 123 cnfine I-O SPICE window to which the search is restricted. 124 result O SPICE window containing results. 125 126 -Detailed_Input 127 128 129 occtyp indicates the type of occultation that is to be found. 130 Supported values and corresponding definitions are: 131 132 "FULL" denotes the full occultation 133 of the body designated by 134 `back' by the body designated 135 by `front', as seen from 136 the location of the observer. 137 In other words, the occulted 138 body is completely invisible 139 as seen from the observer's 140 location. 141 142 "ANNULAR" denotes an annular 143 occultation: the body 144 designated by `front' blocks 145 part of, but not the limb of, 146 the body designated by `back', 147 as seen from the location of 148 the observer. 149 150 "PARTIAL" denotes an partial, 151 non-annular occultation: the 152 body designated by `front' 153 blocks part, but not all, of 154 the limb of the body 155 designated by `back', as seen 156 from the location of the 157 observer. 158 159 "ANY" denotes any of the above three 160 types of occultations: 161 "PARTIAL", "ANNULAR", or 162 "FULL". 163 164 "ANY" should be used to search 165 for times when the body 166 designated by `front' blocks 167 any part of the body designated 168 by `back'. 169 170 The option "ANY" must be used 171 if either the front or back 172 target body is modeled as 173 a point. 174 175 Case and leading or trailing blanks are not 176 significant in the string `occtyp'. 177 178 179 front is the name of the target body that occults---that is, 180 passes in front of---the other. Optionally, you may 181 supply the integer NAIF ID code for the body as a 182 string. For example both "MOON" and "301" are 183 legitimate strings that designate the Moon. 184 185 Case and leading or trailing blanks are not 186 significant in the string `front'. 187 188 189 fshape is a string indicating the geometric model used to 190 represent the shape of the front target body. The 191 supported options are: 192 193 "ELLIPSOID" Use a triaxial ellipsoid model 194 with radius values provided via the 195 kernel pool. A kernel variable 196 having a name of the form 197 198 "BODYnnn_RADII" 199 200 where nnn represents the NAIF 201 integer code associated with the 202 body, must be present in the kernel 203 pool. This variable must be 204 associated with three numeric 205 values giving the lengths of the 206 ellipsoid's X, Y, and Z semi-axes. 207 208 "POINT" Treat the body as a single point. 209 When a point target is specified, 210 the occultation type must be 211 set to "ANY". 212 213 214 "DSK/UNPRIORITIZED[/SURFACES = <surface list>]" 215 216 Use topographic data provided by DSK files to 217 model the body's shape. These data must be 218 provided by loaded DSK files. 219 220 The surface list specification is optional. The 221 syntax of the list is 222 223 <surface 1> [, <surface 2>...] 224 225 If present, it indicates that data only for the 226 listed surfaces are to be used; however, data 227 need not be available for all surfaces in the 228 list. If absent, loaded DSK data for any surface 229 associated with the target body are used. 230 231 The surface list may contain surface names or 232 surface ID codes. Names containing blanks must 233 be delimited by double quotes, for example 234 235 SURFACES = "Mars MEGDR 128 PIXEL/DEG" 236 237 If multiple surfaces are specified, their names 238 or IDs must be separated by commas. 239 240 See the Particulars section below for details 241 concerning use of DSK data. 242 243 The combinations of the shapes of the target bodies 244 `front' and `back' must be one of: 245 246 One ELLIPSOID, one POINT 247 Two ELLIPSOIDs 248 One DSK, one POINT 249 250 Case and leading or trailing blanks are not 251 significant in the string `fshape'. 252 253 254 fframe is the name of the body-fixed, body-centered reference 255 frame associated with the front target body. Examples 256 of such names are "IAU_SATURN" (for Saturn) and 257 "ITRF93" (for the Earth). 258 259 If the front target body is modeled as a point, `fframe' 260 should be left empty or blank. 261 262 Case and leading or trailing blanks bracketing a 263 non-blank frame name are not significant in the string 264 `fframe'. 265 266 267 back is the name of the target body that is occulted 268 by---that is, passes in back of---the other. 269 Optionally, you may supply the integer NAIF ID code 270 for the body as a string. For example both "MOON" and 271 "301" are legitimate strings that designate the Moon. 272 273 Case and leading or trailing blanks are not 274 significant in the string `back'. 275 276 277 bshape is the shape specification for the body designated 278 by `back'. See the description of `fshape' above for 279 details. 280 281 282 bframe is the name of the body-fixed, body-centered reference 283 frame associated with the ``back'' target body. 284 Examples of such names are "IAU_SATURN" (for Saturn) 285 and "ITRF93" (for the Earth). 286 287 If the back target body is modeled as a point, `bframe' 288 should be left empty or blank. 289 290 Case and leading or trailing blanks bracketing a 291 non-blank frame name are not significant in the string 292 `bframe'. 293 294 295 abcorr indicates the aberration corrections to be applied to 296 the state of the target body to account for one-way 297 light time. Stellar aberration corrections are 298 ignored if specified, since these corrections don't 299 improve the accuracy of the occultation determination. 300 301 See the header of the SPICE routine spkezr_c for a 302 detailed description of the aberration correction 303 options. For convenience, the options supported by 304 this routine are listed below: 305 306 "NONE" Apply no correction. 307 308 "LT" "Reception" case: correct for 309 one-way light time using a Newtonian 310 formulation. 311 312 "CN" "Reception" case: converged 313 Newtonian light time correction. 314 315 "XLT" "Transmission" case: correct for 316 one-way light time using a Newtonian 317 formulation. 318 319 "XCN" "Transmission" case: converged 320 Newtonian light time correction. 321 322 Case and blanks are not significant in the string 323 `abcorr'. 324 325 326 obsrvr is the name of the body from which the occultation is 327 observed. Optionally, you may supply the integer NAIF 328 ID code for the body as a string. 329 330 Case and leading or trailing blanks are not 331 significant in the string `obsrvr'. 332 333 334 tol is a tolerance value used to determine convergence of 335 root-finding operations. `tol' is measured in TDB seconds 336 and must be greater than zero. 337 338 339 udstep is an externally specified routine that computes a 340 time step in an attempt to find a transition of the 341 state being considered. In the context of this 342 routine's algorithm, a "state transition" occurs where 343 the state changes from being "in occultation" to being 344 "not in occultation" or vice versa. 345 346 This routine relies on `udstep' returning step sizes 347 small enough so that state transitions within the 348 confinement window are not overlooked. There must 349 never be two roots A and B separated by less than 350 `step', where `step' is the minimum step size returned by 351 `udstep' for any value of `et'; in the interval [A, B]. 352 353 The prototype for `udstep' is 354 355 void ( * udstep ) ( SpiceDouble et, 356 SpiceDouble * step ) 357 358 where: 359 360 et is the input start time from which the 361 algorithm is to search forward for a state 362 transition. `et' is expressed as seconds past 363 J2000 TDB. 364 365 step is the output step size. `step' indicates 366 how far to advance `et' so that `et' and 367 et+step may bracket a state transition and 368 definitely do not bracket more than one 369 state transition. Units are TDB seconds. 370 371 If a constant step size is desired, the CSPICE routine 372 373 gfstep_c 374 375 may be used as the step size function. If gfstep_c is 376 used, the step size must be set by calling gfsstp_c prior 377 to calling this routine. 378 379 380 udrefn is the name of the externally specified routine that 381 computes a refinement in the times that bracket a 382 transition point. In other words, once a pair of 383 times have been detected such that the system is in 384 different states at each of the two times, `udrefn' 385 selects an intermediate time which should be closer to 386 the transition state than one of the two known times. 387 The prototype for `udrefn' is: 388 389 void ( * udrefn ) ( SpiceDouble t1, 390 SpiceDouble t2, 391 SpiceBoolean s1, 392 SpiceBoolean s2, 393 SpiceDouble * t ) 394 395 where the inputs are: 396 397 t1 is a time when the system is in state `s1'. `t1' 398 is expressed as seconds past J2000 TDB. 399 400 t2 is a time when the system is in state `s2'. `t2' 401 is expressed as seconds past J2000 TDB. `t2' is 402 assumed to be larger than `t1'. 403 404 s1 is the state of the system at time t1. 405 406 s2 is the state of the system at time t2. 407 408 The output is: 409 410 t is next time to check for a state transition. 411 `t' is a number between `t1' and `t2'. `t' is 412 expressed as seconds past J2000 TDB. 413 414 If a simple bisection method is desired, the CSPICE routine 415 gfrefn_c may be used as the refinement function. 416 417 418 rpt is a logical variable which controls whether 419 progress reporting is enabled. When `rpt' is SPICETRUE, 420 progress reporting is enabled and the routines 421 udrepi, udrepu, and udpref (see descriptions below) 422 are used to report progress. 423 424 425 udrepi is a user-defined subroutine that initializes a 426 progress report. When progress reporting is 427 enabled, `udrepi' is called at the start 428 of a search. The prototype for `udrefi' is 429 430 void ( * udrepi ) ( SpiceCell * cnfine, 431 ConstSpiceChar * srcpre, 432 ConstSpiceChar * srcsuf ) 433 434 where 435 436 cnfine 437 438 is a confinement window specifying the time period 439 over which a search is conducted, and 440 441 srcpre 442 srcsuf 443 444 are prefix and suffix strings used in the progress 445 report: these strings are intended to bracket a 446 representation of the fraction of work done. For 447 example, when the CSPICE progress reporting functions 448 are used, if srcpre and srcsuf are, respectively, 449 450 "Occultation/transit search" 451 "done." 452 453 the progress report display at the end of 454 the search will be: 455 456 Occultation/transit search 100.00% done. 457 458 The CSPICE routine gfrepi_c may be used as the 459 actual argument corresponding to `udrepi'. If so, 460 the CSPICE routines gfrepu_c and gfrepf_c must be 461 the actual arguments corresponding to `udrepu' and 462 `udrepf'. 463 464 465 udrepu is a user-defined subroutine that updates the 466 progress report for a search. The prototype 467 of `udrepu' is 468 469 void ( * udrepu ) ( SpiceDouble ivbeg, 470 SpiceDouble ivend, 471 SpiceDouble et ) 472 473 In order for a meaningful progress report to be displayed, 474 `ivbeg' and `ivend' must satisfy the following constraints: 475 476 - `ivbeg' must be less than or equal to `ivend'. 477 478 - Over a search, the sum of the differences 479 480 ivend - ivbeg 481 482 for all calls to this routine made during the search 483 must equal the measure (that is, the sum of the 484 lengths of the intervals) of the confinement window 485 `cnfine'. 486 487 `et' is the current time reached in the search for an event. 488 `et' must lie in the interval 489 490 ivbeg : ivend 491 492 inclusive. The input values of `et' for a given interval 493 need not form an increasing sequence. 494 495 The CSPICE routine gfrepu_c may be used as the actual 496 argument corresponding to `udrepu'. If so, the CSPICE 497 routines gfrepi_c and gfrepf_c must be the actual 498 arguments corresponding to `udrepi' and `udrepf'. 499 500 501 udrepf is a user-defined subroutine that finalizes a progress 502 report. `udrepf' has no arguments. 503 504 The CSPICE routine gfrepf_c may be used as the actual 505 argument corresponding to `udrepf'. If so, the CSPICE 506 routines gfrepi_c and gfrepu_c must be the actual 507 arguments corresponding to `udrepi' and `udrepu'. 508 509 510 bail is a logical variable indicating whether or not 511 interrupt handling is enabled. When `bail' is 512 set to SPICETRUE, the input function `udbail' (see 513 description below) is used to determine whether 514 an interrupt has been issued. 515 516 517 udbail is the name of a user defined logical function that 518 indicates whether an interrupt signal has been 519 issued (for example, from the keyboard). udbail 520 has the prototype 521 522 SpiceBoolean ( * udbail ) ( void ) 523 524 The return value is SPICETRUE if an interrupt has 525 been issued; otherwise the value is SPICEFALSE. 526 527 gfocce_c uses `udbail' only when `bail' (see above) is set 528 to SPICETRUE, indicating that interrupt handling is 529 enabled. When interrupt handling is enabled, gfocce_c 530 and routines in its call tree will call `udbail' to 531 determine whether to terminate processing and return 532 immediately. 533 534 If the user doesn't wish to provide a custom interrupt 535 handling function, the CSPICE routine 536 537 gfbail_c 538 539 may be used. 540 541 The function `udbail' will be usually be tested 542 multiple times by the GF system between the time 543 an interrupt is issued and the time when 544 control is returned to the calling program, so 545 `udbail' nmust continue to return SPICETRUE 546 until explicitly reset by the calling application. 547 So `udbail' must provide a "reset" mechanism." 548 In the case of gfbail_c, the reset function is 549 550 gfclrh_c 551 552 If interrupt handing is not enabled, a logical 553 function must still be passed to gfocce_c as 554 an input argument. The CSPICE function 555 556 gfbail_c 557 558 may be used for this purpose. 559 560 See the Examples header section below for a complete code 561 example demonstrating use of the CSPICE interrupt 562 handling capability. 563 564 565 cnfine is a SPICE window that confines the time period over 566 which the specified search is conducted. `cnfine' may 567 consist of a single interval or a collection of 568 intervals. 569 570 The endpoints of the time intervals comprising `cnfine' 571 are interpreted as seconds past J2000 TDB. 572 573 See the Examples section below for a code example 574 that shows how to create a confinement window. 575 576 577 -Detailed_Output 578 579 cnfine is the input confinement window, updated if necessary 580 so the control area of its data array indicates the 581 window's size and cardinality. The window data are 582 unchanged. 583 584 585 result is a SPICE window representing the set of time 586 intervals, within the confinement period, when the 587 specified occultation occurs. 588 589 The endpoints of the time intervals comprising `result' 590 are interpreted as seconds past J2000 TDB. 591 592 If `result' is non-empty on input, its contents 593 will be discarded before gfocce_c conducts its 594 search. 595 596 -Parameters 597 598 None. 599 600 -Exceptions 601 602 1) In order for this routine to produce correct results, 603 the step size must be appropriate for the problem at hand. 604 Step sizes that are too large may cause this routine to miss 605 roots; step sizes that are too small may cause this routine 606 to run unacceptably slowly and in some cases, find spurious 607 roots. 608 609 This routine does not diagnose invalid step sizes, except 610 that if the step size is non-positive, the error 611 SPICE(INVALIDSTEPSIZE) will be signaled. 612 613 2) Due to numerical errors, in particular, 614 615 - Truncation error in time values 616 - Finite tolerance value 617 - Errors in computed geometric quantities 618 619 it is *normal* for the condition of interest to not always be 620 satisfied near the endpoints of the intervals comprising the 621 result window. 622 623 The result window may need to be contracted slightly by the 624 caller to achieve desired results. The SPICE window routine 625 wncond_c can be used to contract the result window. 626 627 3) If name of either target or the observer cannot be translated 628 to a NAIF ID code, the error will be diagnosed by a routine 629 in the call tree of this routine. 630 631 4) If the radii of a target body modeled as an ellipsoid cannot 632 be determined by searching the kernel pool for a kernel 633 variable having a name of the form 634 635 "BODYnnn_RADII" 636 637 where nnn represents the NAIF integer code associated with 638 the body, the error will be diagnosed by a routine in the 639 call tree of this routine. 640 641 5) If either of the target bodies `front' or `back' coincides with 642 the observer body `obsrvr', the error will be diagnosed by a 643 routine in the call tree of this routine. 644 645 6) If the body designated by `front' coincides with that 646 designated by `back', the error will be diagnosed by a routine 647 in the call tree of this routine. 648 649 7) If either of the body model specifiers `fshape' or `bshape' 650 is not recognized, the error will be diagnosed by a routine 651 in the call tree of this routine. 652 653 8) If both of the body model specifiers `fshape' and `bshape' 654 specify point targets, the error will be diagnosed by a 655 routine in the call tree of this routine. 656 657 9) If a target body-fixed reference frame associated with a 658 non-point target is not recognized, the error will be 659 diagnosed by a routine in the call tree of this routine. 660 661 10) If a target body-fixed reference frame is not centered at 662 the corresponding target body, the error will be 663 diagnosed by a routine in the call tree of this routine. 664 665 11) If the loaded kernels provide insufficient data to 666 compute the requested state vector, the deficiency will 667 be diagnosed by a routine in the call tree of this routine. 668 669 12) If an error occurs while reading an SPK or other kernel file, 670 the error will be diagnosed by a routine in the call tree 671 of this routine. 672 673 13) If the output SPICE window `result' has insufficient capacity 674 to contain the number of intervals on which the specified 675 occultation condition is met, the error will be diagnosed 676 by a routine in the call tree of this routine. 677 678 14) If a point target is specified and the occultation 679 type is set to a valid value other than "ANY", the 680 error will be diagnosed by a routine in the call tree 681 of this routine. 682 683 15) Invalid aberration correction specifications will be 684 diagnosed by a routine in the call tree of this routine. 685 686 16) If either `fshape' or `bshape' specifies that the target surface 687 is represented by DSK data, and no DSK files are loaded for 688 the specified target, the error is signaled by a routine in 689 the call tree of this routine. 690 691 17) If either `fshape' or `bshape' specifies that the target surface 692 is represented by DSK data, but the shape specification is 693 invalid, the error is signaled by a routine in the call tree 694 of this routine. 695 696 18) If any input string argument pointer is null, the error 697 SPICE(NULLPOINTER) will be signaled. 698 699 19) If any input string argument, other than `fframe' or `bframe', 700 is empty, the error SPICE(EMPTYSTRING) will be signaled. 701 702 20) If the convergence tolerance size is non-positive, the error 703 SPICE(INVALIDTOLERANCE) will be signaled. 704 705 21) If the occultation type is not recognized, the error 706 SPICE(INVALIDOCCTYPE) is signaled. 707 708 22) If any attempt to change the handler for the interrupt 709 signal SIGINT fails, the error SPICE(SIGNALFAILURE) is 710 signaled. 711 712 23) If operation of this routine is interrupted, the output result 713 window will be invalid. 714 715 716 -Files 717 718 719 Appropriate SPICE kernels must be loaded by the calling program 720 before this routine is called. 721 722 The following data are required: 723 724 - SPK data: the calling application must load ephemeris data 725 for the targets, source and observer that cover the time 726 period specified by the window `cnfine'. If aberration 727 corrections are used, the states of the target bodies and of 728 the observer relative to the solar system barycenter must be 729 calculable from the available ephemeris data. Typically 730 ephemeris data are made available by loading one or more SPK 731 files via furnsh_c. 732 733 - PCK data: bodies modeled as triaxial ellipsoids must have 734 semi-axis lengths provided by variables in the kernel pool. 735 Typically these data are made available by loading a text 736 PCK file via furnsh_c. 737 738 - FK data: if either of the reference frames designated by 739 `bframe' or `fframe' are not built in to the SPICE system, 740 one or more FKs specifying these frames must be loaded. 741 742 The following data may be required: 743 744 - DSK data: if either `fshape' or `bshape' indicates that DSK 745 data are to be used, DSK files containing topographic data 746 for the target body must be loaded. If a surface list is 747 specified, data for at least one of the listed surfaces must 748 be loaded. 749 750 - Surface name-ID associations: if surface names are specified 751 in `fshape' or `bshape', the association of these names with 752 their corresponding surface ID codes must be established by 753 assignments of the kernel variables 754 755 NAIF_SURFACE_NAME 756 NAIF_SURFACE_CODE 757 NAIF_SURFACE_BODY 758 759 Normally these associations are made by loading a text 760 kernel containing the necessary assignments. An example 761 of such a set of assignments is 762 763 NAIF_SURFACE_NAME += 'Mars MEGDR 128 PIXEL/DEG' 764 NAIF_SURFACE_CODE += 1 765 NAIF_SURFACE_BODY += 499 766 767 - CK data: either of the body-fixed frames to which `fframe' or 768 `bframe' refer might be a CK frame. If so, at least one CK 769 file will be needed to permit transformation of vectors 770 between that frame and the J2000 frame. 771 772 - SCLK data: if a CK file is needed, an associated SCLK 773 kernel is required to enable conversion between encoded SCLK 774 (used to time-tag CK data) and barycentric dynamical time 775 (TDB). 776 777 Kernel data are normally loaded once per program run, NOT every 778 time this routine is called. 779 780 781 -Particulars 782 783 This routine provides the SPICE GF system's most flexible 784 interface for searching for occultation events. 785 786 Applications that require do not require support for progress 787 reporting, interrupt handling, non-default step or refinement 788 functions, or non-default convergence tolerance normally should 789 call gfoclt_c rather than this routine. 790 791 This routine determines a set of one or more time intervals 792 within the confinement window when a specified type of 793 occultation occurs. The resulting set of intervals is returned as 794 a SPICE window. 795 796 Below we discuss in greater detail aspects of this routine's 797 solution process that are relevant to correct and efficient 798 use of this routine in user applications. 799 800 801 The Search Process 802 ================== 803 804 The search for occultations is treated as a search for state 805 transitions: times are sought when the state of the BACK body 806 changes from "not occulted" to "occulted" or vice versa. 807 808 Step Size 809 ========= 810 811 Each interval of the confinement window is searched as follows: 812 first, the input step size is used to determine the time 813 separation at which the occultation state will be sampled. 814 Starting at the left endpoint of an interval, samples will be 815 taken at each step. If a state change is detected, a root has 816 been bracketed; at that point, the "root"--the time at which the 817 state change occurs---is found by a refinement process, for 818 example, via binary search. 819 820 Note that the optimal choice of step size depends on the lengths 821 of the intervals over which the occultation state is constant: 822 the step size should be shorter than the shortest occultation 823 duration and the shortest period between occultations, within 824 the confinement window. 825 826 Having some knowledge of the relative geometry of the targets and 827 observer can be a valuable aid in picking a reasonable step size. 828 In general, the user can compensate for lack of such knowledge by 829 picking a very short step size; the cost is increased computation 830 time. 831 832 Note that the step size is not related to the precision with which 833 the endpoints of the intervals of the result window are computed. 834 That precision level is controlled by the convergence tolerance. 835 836 837 Convergence Tolerance 838 ===================== 839 840 Once a root has been bracketed, a refinement process is used to 841 narrow down the time interval within which the root must lie. This 842 refinement process terminates when the location of the root has been 843 determined to within an error margin called the "convergence 844 tolerance." The convergence tolerance used by high-level GF routines 845 that call this routine is set via the parameter SPICE_GF_CNVTOL, 846 which is declared in the header file SpiceGF.h. 847 848 The value of SPICE_GF_CNVTOL is set to a "tight" value so that the 849 tolerance doesn't become the limiting factor in the accuracy of 850 solutions found by this routine. In general the accuracy of input 851 data will be the limiting factor. 852 853 Making the tolerance tighter than SPICE_GF_CNVTOL is unlikely to be 854 useful, since the results are unlikely to be more accurate. Making 855 the tolerance looser will speed up searches somewhat, since a few 856 convergence steps will be omitted. However, in most cases, the step 857 size is likely to have a much greater affect on processing time than 858 would the convergence tolerance. 859 860 861 The Confinement Window 862 ====================== 863 864 The simplest use of the confinement window is to specify a time 865 interval within which a solution is sought. However, the confinement 866 window can, in some cases, be used to make searches more efficient. 867 Sometimes it's possible to do an efficient search to reduce the size 868 of the time period over which a relatively slow search of interest 869 must be performed. For an example, see the program CASCADE in the GF 870 Example Programs chapter of the GF Required Reading, gf.req. 871 872 873 Using DSK data 874 ============== 875 876 DSK loading and unloading 877 ------------------------- 878 879 DSK files providing data used by this routine are loaded by 880 calling furnsh_c and can be unloaded by calling unload_c or 881 kclear_c. See the documentation of furnsh_c for limits on numbers 882 of loaded DSK files. 883 884 For run-time efficiency, it's desirable to avoid frequent 885 loading and unloading of DSK files. When there is a reason to 886 use multiple versions of data for a given target body---for 887 example, if topographic data at varying resolutions are to be 888 used---the surface list can be used to select DSK data to be 889 used for a given computation. It is not necessary to unload 890 the data that are not to be used. This recommendation presumes 891 that DSKs containing different versions of surface data for a 892 given body have different surface ID codes. 893 894 895 DSK data priority 896 ----------------- 897 898 A DSK coverage overlap occurs when two segments in loaded DSK 899 files cover part or all of the same domain---for example, a 900 given longitude-latitude rectangle---and when the time 901 intervals of the segments overlap as well. 902 903 When DSK data selection is prioritized, in case of a coverage 904 overlap, if the two competing segments are in different DSK 905 files, the segment in the DSK file loaded last takes 906 precedence. If the two segments are in the same file, the 907 segment located closer to the end of the file takes 908 precedence. 909 910 When DSK data selection is unprioritized, data from competing 911 segments are combined. For example, if two competing segments 912 both represent a surface as a set of triangular plates, the 913 union of those sets of plates is considered to represent the 914 surface. 915 916 Currently only unprioritized data selection is supported. 917 Because prioritized data selection may be the default behavior 918 in a later version of the routine, the UNPRIORITIZED keyword is 919 required in the `fshape' and `bshape' arguments. 920 921 922 Syntax of the shape input arguments for the DSK case 923 ---------------------------------------------------- 924 925 The keywords and surface list in the target shape arguments 926 `bshape' and `fshape' are called "clauses." The clauses may 927 appear in any order, for example 928 929 "DSK/<surface list>/UNPRIORITIZED" 930 "DSK/UNPRIORITIZED/<surface list>" 931 "UNPRIORITIZED/<surface list>/DSK" 932 933 The simplest form of the `method' argument specifying use of 934 DSK data is one that lacks a surface list, for example: 935 936 "DSK/UNPRIORITIZED" 937 938 For applications in which all loaded DSK data for the target 939 body are for a single surface, and there are no competing 940 segments, the above string suffices. This is expected to be 941 the usual case. 942 943 When, for the specified target body, there are loaded DSK 944 files providing data for multiple surfaces for that body, the 945 surfaces to be used by this routine for a given call must be 946 specified in a surface list, unless data from all of the 947 surfaces are to be used together. 948 949 The surface list consists of the string 950 951 "SURFACES = " 952 953 followed by a comma-separated list of one or more surface 954 identifiers. The identifiers may be names or integer codes in 955 string format. For example, suppose we have the surface 956 names and corresponding ID codes shown below: 957 958 Surface Name ID code 959 ------------ ------- 960 "Mars MEGDR 128 PIXEL/DEG" 1 961 "Mars MEGDR 64 PIXEL/DEG" 2 962 "Mars_MRO_HIRISE" 3 963 964 If data for all of the above surfaces are loaded, then 965 data for surface 1 can be specified by either 966 967 "SURFACES = 1" 968 969 or 970 971 "SURFACES = \"Mars MEGDR 128 PIXEL/DEG\"" 972 973 Escaped double quotes are used to delimit the surface name because 974 it contains blank characters. 975 976 To use data for surfaces 2 and 3 together, any 977 of the following surface lists could be used: 978 979 "SURFACES = 2, 3" 980 981 "SURFACES = \"Mars MEGDR 64 PIXEL/DEG\", 3" 982 983 "SURFACES = 2, Mars_MRO_HIRISE" 984 985 "SURFACES = \"Mars MEGDR 64 PIXEL/DEG\", Mars_MRO_HIRISE" 986 987 An example of a shape argument that could be constructed 988 using one of the surface lists above is 989 990 "DSK/UNPRIORITIZED/SURFACES = \"Mars MEGDR 64 PIXEL/DEG\", 3" 991 992 993 -Examples 994 995 996 The numerical results shown for these examples may differ across 997 platforms. The results depend on the SPICE kernels used as 998 input, the compiler and supporting libraries, and the machine 999 specific arithmetic implementation. 1000 1001 1002 1) Conduct a search using default GF progress reporting 1003 and interrupt handling capabilities. 1004 1005 The program will use console I/O to display a simple 1006 ASCII-based progress report. 1007 1008 The program will trap keyboard interrupts (on most systems, 1009 generated by typing the "control C" key combination). This 1010 feature can be used in non-trivial applications to allow 1011 the application to continue after a search as been interrupted. 1012 1013 The program will find occultations of the Sun by the Moon as seen 1014 from the center of the Earth over the month December, 2001. 1015 1016 Use light time corrections to model apparent positions of Sun 1017 and Moon. Stellar aberration corrections are not specified 1018 because they don't affect occultation computations. 1019 1020 We select a step size of 20 seconds, which implies we ignore 1021 occultation events lasting less than 20 seconds, if any exist. 1022 Given this step size and the length of the search interval, the 1023 user has time to interrupt the computation. In an interactive 1024 setting, the user might speed up the search by lengthening the 1025 step size or shortening the search interval, as long as these 1026 adjustments don't prevent the search from finding the correct 1027 solution. 1028 1029 Use the meta-kernel shown below to load the required SPICE 1030 kernels. 1031 1032 KPL/MK 1033 1034 File name: standard.tm 1035 1036 This meta-kernel is intended to support operation of SPICE 1037 example programs. The kernels shown here should not be 1038 assumed to contain adequate or correct versions of data 1039 required by SPICE-based user applications. 1040 1041 In order for an application to use this meta-kernel, the 1042 kernels referenced here must be present in the user's 1043 current working directory. 1044 1045 1046 \begindata 1047 1048 KERNELS_TO_LOAD = ( 'de421.bsp', 1049 'pck00008.tpc', 1050 'naif0009.tls' ) 1051 1052 \begintext 1053 1054 1055 Example code begins here. 1056 1057 1058 #include "SpiceUsr.h" 1059 #include <stdio.h> 1060 1061 int main() 1062 { 1063 /. 1064 Constants 1065 ./ 1066 #define TIMFMT "YYYY MON DD HR:MN:SC.###### ::TDB (TDB)" 1067 #define CNVTOL 1.e-6 1068 #define MAXWIN 200 1069 #define TIMLEN 41 1070 1071 /. 1072 Local variables 1073 ./ 1074 SpiceBoolean bail; 1075 SpiceBoolean rpt; 1076 1077 SpiceChar * win0; 1078 SpiceChar * win1; 1079 SpiceChar begstr [ TIMLEN ]; 1080 SpiceChar endstr [ TIMLEN ]; 1081 1082 SPICEDOUBLE_CELL ( cnfine, MAXWIN ); 1083 SPICEDOUBLE_CELL ( result, MAXWIN ); 1084 1085 SpiceDouble et0; 1086 SpiceDouble et1; 1087 SpiceDouble left; 1088 SpiceDouble right; 1089 1090 SpiceInt i; 1091 1092 /. 1093 Load kernels. 1094 ./ 1095 furnsh_c ( "standard.tm" ); 1096 1097 /. 1098 Obtain the TDB time bounds of the confinement 1099 window, which is a single interval in this case. 1100 ./ 1101 win0 = "2001 DEC 10 00:00:00 TDB"; 1102 win1 = "2002 JAN 01 00:00:00 TDB"; 1103 1104 str2et_c ( win0, &et0 ); 1105 str2et_c ( win1, &et1 ); 1106 1107 /. 1108 Insert the time bounds into the confinement 1109 window. 1110 ./ 1111 wninsd_c ( et0, et1, &cnfine ); 1112 1113 /. 1114 Select a twenty-second step. We'll ignore any occultations 1115 lasting less than 20 seconds. 1116 ./ 1117 gfsstp_c ( 20.0 ); 1118 1119 /. 1120 Turn on interrupt handling and progress reporting. 1121 ./ 1122 bail = SPICETRUE; 1123 rpt = SPICETRUE; 1124 1125 /. 1126 Perform the search. 1127 ./ 1128 gfocce_c ( "ANY", 1129 "MOON", "ellipsoid", "IAU_MOON", 1130 "SUN", "ellipsoid", "IAU_SUN", 1131 "LT", "EARTH", CNVTOL, 1132 gfstep_c, gfrefn_c, rpt, 1133 gfrepi_c, gfrepu_c, gfrepf_c, 1134 bail, gfbail_c, &cnfine, 1135 &result ); 1136 1137 1138 if ( gfbail_c() ) 1139 { 1140 /. 1141 Clear the CSPICE interrupt indication. This is 1142 an essential step for programs that continue 1143 running after an interrupt; gfbail_c will 1144 continue to return SPICETRUE until this step 1145 has been performed. 1146 ./ 1147 gfclrh_c(); 1148 1149 1150 /. 1151 We've trapped an interrupt signal. In a realistic 1152 application, the program would continue operation 1153 from this point. In this simple example, we simply 1154 display a message and quit. 1155 ./ 1156 printf ( "\nSearch was interrupted.\n\nThis message " 1157 "was written after an interrupt signal\n" 1158 "was trapped. By default, the program " 1159 "would have terminated \nbefore this message " 1160 "could be written.\n\n" ); 1161 } 1162 else 1163 { 1164 1165 if ( wncard_c(&result) == 0 ) 1166 { 1167 printf ( "No occultation was found.\n" ); 1168 } 1169 else 1170 { 1171 for ( i = 0; i < wncard_c(&result); i++ ) 1172 { 1173 /. 1174 fetch and display each occultation interval. 1175 ./ 1176 wnfetd_c ( &result, i, &left, &right ); 1177 1178 timout_c ( left, TIMFMT, TIMLEN, begstr ); 1179 timout_c ( right, TIMFMT, TIMLEN, endstr ); 1180 1181 printf ( "Interval %d\n", (int)i ); 1182 printf ( " Start time: %s\n", begstr ); 1183 printf ( " Stop time: %s\n", endstr ); 1184 } 1185 } 1186 1187 } 1188 1189 return ( 0 ); 1190 } 1191 1192 When this program was executed on a PC/Linux/gcc platform, the 1193 progress report had the format shown below: 1194 1195 Occultation/transit search 6.02% done. 1196 1197 The completion percentage was updated approximately once per 1198 second. 1199 1200 When this program completed execution, the output was: 1201 1202 1203 Occultation/transit search 100.00% done. 1204 1205 interval 0 1206 start time: 2001 DEC 14 20:10:14.195952 (TDB) 1207 stop time: 2001 DEC 14 21:35:50.317994 (TDB) 1208 1209 1210 When the program was interrupted at an arbitrary time, 1211 the output was: 1212 1213 Occultation/transit search 13.63% done. 1214 Search was interrupted. 1215 1216 This message was written after an interrupt signal 1217 was trapped. By default, the program would have terminated 1218 before this message could be written. 1219 1220 1221 -Restrictions 1222 1223 1) If the caller passes in the default, constant step 1224 size routine, gfstep_c, the caller must set the step 1225 size by calling the entry point gfsstp_c before 1226 calling gfocce_c. The call syntax for gfsstp_c is 1227 1228 gfsstp_c ( step ); 1229 1230 1231 -Literature_References 1232 1233 None. 1234 1235 -Author_and_Institution 1236 1237 N.J. Bachman (JPL) 1238 L.S. Elson (JPL) 1239 W.L. Taber (JPL) 1240 I.M. Underwood (JPL) 1241 E.D. Wright (JPL) 1242 1243 -Version 1244 1245 -CSPICE Version 2.0.0, 29-FEB-2016 (NJB) (EDW) 1246 1247 Edit to example program to use "%d" with explicit casts 1248 to int for printing SpiceInts with printf. 1249 1250 Updated to support use of DSKs. 1251 1252 -CSPICE Version 1.0.0, 15-APR-2009 (NJB) (LSE) (WLT) (IMU) (EDW) 1253 1254 -Index_Entries 1255 1256 GF mid-level occultation search 1257 1258 -& 1259 */ 1260 1261 { /* Begin gfocce_c */ 1262 1263 /* 1264 Prototypes 1265 */ 1266 void ( * defSigHandler ) (int); 1267 void ( * sigPtr ) (int); 1268 1269 /* 1270 Local variables 1271 */ 1272 logical interrupt; 1273 logical rep; 1274 1275 SpiceBoolean newHandler; 1276 1277 static const SpiceChar * blankStr = " "; 1278 1279 SpiceChar * bFrameStr; 1280 SpiceChar * fFrameStr; 1281 1282 1283 /* 1284 Participate in error tracing. 1285 */ 1286 if ( return_c() ) 1287 { 1288 return; 1289 } 1290 chkin_c ( "gfocce_c" ); 1291 1292 /* 1293 Make sure cell data types are d.p. 1294 */ 1295 CELLTYPECHK2 ( CHK_STANDARD, "gfocce_c", SPICE_DP, cnfine, result ); 1296 1297 1298 /* 1299 Initialize the input cells if necessary. 1300 */ 1301 CELLINIT2 ( cnfine, result ); 1302 1303 1304 /* 1305 The input frame names are special cases because we allow the caller 1306 to pass in empty strings. If either of these strings are empty, 1307 we pass a null-terminated string containing one blank character to 1308 the underlying f2c'd routine. 1309 1310 First make sure the frame name pointers are non-null. 1311 */ 1312 CHKPTR ( CHK_STANDARD, "gfocce_c", bframe ); 1313 CHKPTR ( CHK_STANDARD, "gfocce_c", fframe ); 1314 1315 /* 1316 Use the input frame strings if they're non-empty; otherwise 1317 use blank strings for the frame names. 1318 */ 1319 1320 if ( bframe[0] ) 1321 { 1322 bFrameStr = (SpiceChar *) bframe; 1323 } 1324 else 1325 { 1326 bFrameStr = (SpiceChar *) blankStr; 1327 } 1328 1329 if ( fframe[0] ) 1330 { 1331 fFrameStr = (SpiceChar *) fframe; 1332 } 1333 else 1334 { 1335 fFrameStr = (SpiceChar *) blankStr; 1336 } 1337 1338 1339 /* 1340 Check the other input strings to make sure each pointer is non-null 1341 and each string length is non-zero. 1342 */ 1343 CHKFSTR ( CHK_STANDARD, "gfocce_c", occtyp ); 1344 CHKFSTR ( CHK_STANDARD, "gfocce_c", front ); 1345 CHKFSTR ( CHK_STANDARD, "gfocce_c", fshape ); 1346 CHKFSTR ( CHK_STANDARD, "gfocce_c", back ); 1347 CHKFSTR ( CHK_STANDARD, "gfocce_c", bshape ); 1348 CHKFSTR ( CHK_STANDARD, "gfocce_c", abcorr ); 1349 CHKFSTR ( CHK_STANDARD, "gfocce_c", obsrvr ); 1350 1351 1352 /* 1353 Assign the SpiceBoolean report and interrupt flags. 1354 */ 1355 rep = rpt ; 1356 interrupt = bail; 1357 1358 1359 /* 1360 Store the input function pointers so these functions can be 1361 called by the GF adapters. 1362 */ 1363 zzadsave_c ( UDSTEP, (void *)(udstep) ); 1364 zzadsave_c ( UDREFN, (void *)(udrefn) ); 1365 zzadsave_c ( UDREPF, (void *)(udrepf) ); 1366 zzadsave_c ( UDREPI, (void *)(udrepi) ); 1367 zzadsave_c ( UDREPU, (void *)(udrepu) ); 1368 zzadsave_c ( UDBAIL, (void *)(udbail) ); 1369 1370 1371 /* 1372 If interrupt handling is enabled, and if the default bail-out 1373 routine gfbail_c is being used, set the SPICE interrupt 1374 handler. 1375 */ 1376 1377 newHandler = SPICEFALSE; 1378 1379 if ( bail ) 1380 { 1381 newHandler = ( (void *)udbail == (void *)gfbail_c ); 1382 1383 if ( newHandler ) 1384 { 1385 defSigHandler = signal ( SIGINT, gfinth_c ); 1386 1387 if ( defSigHandler == SIG_ERR ) 1388 { 1389 setmsg_c ( "Attempt to establish the CSPICE routine " 1390 "gfinth_c as the handler for the interrupt " 1391 "signal SIGINT failed." ); 1392 sigerr_c ( "SPICE(SIGNALFAILED)" ); 1393 chkout_c ( "gfocce_c" ); 1394 return; 1395 } 1396 } 1397 } 1398 1399 1400 /* 1401 Let the f2c'd routine do the work. 1402 1403 We pass the adapter functions, not those provided as inputs, 1404 to the f2c'd routine. 1405 */ 1406 1407 gfocce_ ( ( char * ) occtyp, 1408 ( char * ) front, 1409 ( char * ) fshape, 1410 ( char * ) fframe, 1411 ( char * ) back, 1412 ( char * ) bshape, 1413 ( char * ) bframe, 1414 ( char * ) abcorr, 1415 ( char * ) obsrvr, 1416 ( doublereal * ) &tol, 1417 ( U_fp ) zzadstep_c, 1418 ( U_fp ) zzadrefn_c, 1419 ( logical * ) &rep, 1420 ( S_fp ) zzadrepi_c, 1421 ( U_fp ) zzadrepu_c, 1422 ( S_fp ) zzadrepf_c, 1423 ( logical * ) &interrupt, 1424 ( L_fp ) zzadbail_c, 1425 ( doublereal * ) (cnfine->base), 1426 ( doublereal * ) (result->base), 1427 ( ftnlen ) strlen(occtyp), 1428 ( ftnlen ) strlen(front), 1429 ( ftnlen ) strlen(fshape), 1430 ( ftnlen ) strlen(fframe), 1431 ( ftnlen ) strlen(back), 1432 ( ftnlen ) strlen(bshape), 1433 ( ftnlen ) strlen(bframe), 1434 ( ftnlen ) strlen(abcorr), 1435 ( ftnlen ) strlen(obsrvr) ); 1436 1437 /* 1438 If we've changed the signal handler, restore the previous one. 1439 */ 1440 if ( newHandler ) 1441 { 1442 sigPtr = signal ( SIGINT, defSigHandler ); 1443 1444 if ( sigPtr == SIG_ERR ) 1445 { 1446 setmsg_c ( "Attempt to restore the previous handler " 1447 "for the interrupt signal SIGINT failed." ); 1448 sigerr_c ( "SPICE(SIGNALFAILED)" ); 1449 chkout_c ( "gfocce_c" ); 1450 return; 1451 } 1452 } 1453 1454 /* 1455 Sync the output cell. 1456 */ 1457 if ( !failed_c() ) 1458 { 1459 zzsynccl_c ( F2C, result ) ; 1460 } 1461 1462 1463 chkout_c ( "gfocce_c" ); 1464 1465 } /* End gfocce_c */ 1466