/* -Procedure getangls_pdt ( Retrieve FOV extents for Cassini instruments ) -Abstract Retrieve the half angles that define the angular extent of Cassini orbiter instrument FOVs. -Copyright Copyright (2001), California Institute of Technology. U.S. Government sponsorship acknowledged. -Required_Reading KERNEL */ #include "SpiceUsr.h" #include "SpiceZst.h" #include "SpiceZmc.h" void getangls_pdt ( ConstSpiceChar * name, SpiceInt shapelen, SpiceChar * shape, SpiceDouble * secang, SpiceDouble * crsang ) /* -Brief_I/O Variable I/O Description -------- --- -------------------------------------------------- name I instrument name. shapelen I space available in the string shape. shape O instrument FOV shape. secang O secondary axis half angle in milliradians. crsang O cross axis half angle in milliradians. -Detailed_Input name is the name of the instrument or FOV of interest. shapelen is the available space in the shape string, counting room for the terminating null. Up to shapelen-1 "data" characters will be assigned to the output string. -Detailed_Output shape is a character string that describes the "shape" of the field of view. Values returned are: "RECTANGULAR" "CIRCULAR" "ELLIPTICAL" Make certain that there is enough room in shape to store each of these strings plus a terminating null. secang is the half angle that describes the angular extent of the detector's field of view that is along the secondary axis specified by the INS[#]_FOV_REF_VECTOR keyword in the FOV definition. crsang is the half angle that describes the angular extent of the detector's field of view that lies along the direction determined by the cross product of the FOV secondary axis with its boresight. In the circular case this angle is the same as secang. -Exceptions 1) If an ID code is not found for name, then this routine signals the error SPICE(IDCODENOTFOUND). 2) If the ID code associated with name is found, but not in the range [-82999, -82000] then the error SPICE(INVALIDIDCODE) is signalled. This routine functions only with Cassini instrument kernels. 3) If the FOV specification used to describe the instrument field of view is something other than the ANGLES specification, then this routine signals the error SPICE(INVALIDFOVSPEC). 4) If the INS[#]_FOV_SHAPE keyword contains anything other than a single string specifying the shape of the FOV, then this routine signals the error SPICE(BADFOVSHAPE). 5) If the INS[#]_FOV_ANGLE_UNITS keyword contains anything other than a single string specifying the angular units, then this routine signals the error SPICE(BADFOVANGLEUNITS). 6) If the INS[#]_FOV_REF_ANGLE keyword contains anything other than a single numeric value, then this routine signals the error SPICE(BADFOVREFANGLE). 7) If the INS[#]_FOV_CROSS_ANGLE keyword for the ELLIPTICAL and RECTANGULAR FOV specifications contains anything other than a single numeric value, then this routine signals the error SPICE(BADFOVCROSSANGLE) 8) If the shape specified in the INS[#]_FOV_SHAPE keyword refers to a shape not listed above in the shape output argument, then this routine signals the error SPICE(UNSUPPORTEDSHAPE). 9) If the units specified in INS[#]_FOV_ANGLE_UNITS do not match the supported ANGLE types listed in the convrt_c header, then the errors SPICE(UNITSNOTREC) or SPICE(INCOMPATIBLEUNITS) will be signalled by convrt_c. -Files getangls_pdt relies on the fact that the necessary instrument kernel has been loaded. -Particulars This routine fetches the shape and angular extents of a field of view definition from the kernel pool and returns it to the caller. The following pictures outline what angles are returned to the caller in the rectangular case: 'secang': --------- secondary axis .| `-. .' | ^ secang `-. | | .' | `-. | .^ .' | |`-. | .' secondary axis | | | `-.|.' x <-------| o----------o boresight | | Boresight | . | .' | .' | .' |.' 'crsang': --------- secondary axis .| `-. .' | ^ crsang `-' | | .' | | .^ .' .|`-. | .' secondary axis | .' | `-.|.' x <-------| o----------o boresight | | Boresight | . | .' | .' | .' |.' The elliptical case is analogous to the rectangular case depicted above. For the circular case, the same half angle is returned in secang and crsang. -Examples The following simple code example loads the UVIS instrument kernel and prints the half angular extents and shape of the CASSINI_UVIS_FUV_HI FOV to standard output. #include "SpiceUsr.h" /. Prototypes ./ void getangls_pdt ( ConstSpiceChar * name, SpiceInt shapelen, SpiceChar * shape, SpiceDouble * secang, SpiceDouble * crsang ); /. Local Parameters ./ #define LNSIZE 32 /. Local Variables ./ SpiceChar shape[LNSIZE]; SpiceDouble secang; SpiceDouble crsang; /. Load the instrument kernel using furnsh. ./ furnsh_c ( "cas_uvis_v04.ti" ); /. Compute the half angles for the UVIS FUV HI FOV. ./ getangls_pdt ( "CASSINI_UVIS_FUV_HI", LNSIZE, shape, &secang, &crsang ); /. Dump the results to standard output. ./ printf ( "CASSINI_UVIS_FUV_HI is a(n) %s FOV with ", shape ); printf ( "a half-angular extent of (%f,%f)", secang, crsang ); printf ( "\n" ); -Restrictions 1) The name of the instrument must be associated with an ID code that is connected with the Cassini orbiter. 2) This routine requires that all of the elements of the FOV definition are correctly specified and accessible from the kernel pool. 3) This routine additionally requires that the FOV specification utilized by the kernels is the 'ANGLES' format. -Literature_References 1) Kernel Required Reading 2) NAIF/SPICE Tutorials 3) Cassini FOV Specification Update Email -Author_and_Institution F.S. Turner (JPL) -Version -getangls_pdt Version 2.0.0, 06-JUN-2001 (FST) Removed the call to the non-standard string function 'strnlen', and replaced it with appropriate code changes. -getangls_pdt Version 1.0.0, 11-APR-2001 (FST) */ { /* Begin getangls_pdt */ /* Local Parameters */ #define MAXKEYSIZE 32 #define MAXSHPSIZE 60 #define MAXSPECSIZE 32 #define MAXUNITSIZE 60 /* Local Variables */ SpiceBoolean gotit = SPICEFALSE; SpiceChar fovspec [ MAXSPECSIZE ] = "CORNERS"; SpiceChar keyword [ MAXKEYSIZE ]; SpiceChar locshap [ MAXSHPSIZE ]; SpiceChar locunit [ MAXUNITSIZE ]; SpiceChar valtype; SpiceDouble loccrs; SpiceDouble locsec; SpiceInt idcode; SpiceInt n; /* Participate in tracing. */ chkin_c ( "getangls_pdt" ); /* Make certain the output frame string has at least enough room for one output character and a null terminator. Also check to see if the input pointer is null. */ CHKOSTR ( CHK_STANDARD, "getangls_pdt", shape, shapelen ); /* Fetch the instrument ID code. */ bodn2c_c ( name, &idcode, &gotit ); if ( gotit == SPICEFALSE ) { setmsg_c ( "Unable to locate ID code for instrument, #." ); errch_c ( "#", name ); sigerr_c ( "SPICE(IDCODENOTFOUND)" ); chkout_c ( "getangls_pdt" ); return; } /* Now verify that this ID code is associated with the Cassini orbiter. */ if ( ( idcode < -89999 ) || ( idcode > -82000 ) ) { setmsg_c ( "The instrument, #, with ID code, #, is not " "associated with the Cassini orbiter. This " "module only functions with Cassini based " "detectors." ); errch_c ( "#", name ); errint_c ( "#", idcode ); sigerr_c ( "SPICE(INVALIDIDCODE)" ); chkout_c ( "getangls_pdt" ); return; } /* Retrieve the FOV parameters for this instrument from the kernel pool. First check to make certain that this instrument is using the proper specification. */ sprintf ( keyword, "INS%ld_FOV_CLASS_SPEC", idcode ); /* Initialize n to 0 just to satiate the gcpool_c wrapper. */ n = 0; gcpool_c ( keyword, 0, 1, MAXSPECSIZE, &n, fovspec, &gotit ); if ( (gotit == SPICEFALSE) || !eqstr_c("ANGLES", fovspec) ) { setmsg_c ( "The instrument, #, utilizes the FOV " "specification, #. This specification is not " "currently supported by this module." ); errch_c ( "#", name ); errch_c ( "#", fovspec ); sigerr_c ( "SPICE(INVALIDFOVSPEC)" ); chkout_c ( "getangls_pdt" ); return; } /* Fetch the shape of the instrument's FOV. */ sprintf ( keyword, "INS%ld_FOV_SHAPE", idcode ); dtpool_c ( keyword, &gotit, &n, &valtype ); if ( (n != 1) || (gotit == SPICEFALSE) || (valtype != 'C' ) ) { setmsg_c ( "The FOV shape for instrument # is missing or " "improperly defined. Check the " "kernels you are loading for INS#_FOV_SHAPE." ); errch_c ( "#", name ); errint_c ( "#", idcode ); sigerr_c ( "SPICE(BADFOVSHAPE)" ); chkout_c ( "getangls_pdt" ); return; } /* Initialize n to 0 just to satiate the gcpool_c wrapper. */ n = 0; gcpool_c ( keyword, 0, 1, MAXSHPSIZE, &n, locshap, &gotit ); /* Convert the string to a C style string, since gcpool_c as of N0051 does not do this. */ F2C_ConvertStr ( MAXSHPSIZE, locshap ); /* Now retrieve the angles of interest from the kernel. All FOV definitions that conform to the ANGLES specification will possess the keyword INS[#]_FOV_REF_ANGLE and INS[#]_FOV_ANGLE_UNITS. INS[#]_FOV_CROSS_ANGLE is unused in the circular case. Fetch the units of the instrument's FOV angular specification. */ sprintf ( keyword, "INS%ld_FOV_ANGLE_UNITS", idcode ); dtpool_c ( keyword, &gotit, &n, &valtype ); if ( (n != 1) || (gotit == SPICEFALSE) || (valtype != 'C' ) ) { setmsg_c ( "The FOV angular unit specification for " "instrument # is missing or improperly " "defined. Check the kernels you are loading " "for INS#_FOV_ANGLE_UNITS." ); errch_c ( "#", name ); errint_c ( "#", idcode ); sigerr_c ( "SPICE(BADFOVANGLEUNITS)" ); chkout_c ( "getangls_pdt" ); return; } /* Initialize n to 0 just to satiate the gcpool_c wrapper. */ n = 0; gcpool_c ( keyword, 0, 1, MAXUNITSIZE, &n, locunit, &gotit ); /* Convert the string to a C style string, since gcpool_c as of N0051 does not do this. */ F2C_ConvertStr ( MAXUNITSIZE, locunit ); /* Fetch the FOV_REF_ANGLE. */ sprintf ( keyword, "INS%ld_FOV_REF_ANGLE", idcode ); dtpool_c ( keyword, &gotit, &n, &valtype ); if ( (n != 1) || (gotit == SPICEFALSE) || (valtype != 'N') ) { setmsg_c ( "The FOV reference angle for instrument # is " "missing or improperly defined. Check the " "kernels you are loading for " "INS#_FOV_REF_ANGLE." ); errch_c ( "#", name ); errint_c ( "#", idcode ); sigerr_c ( "SPICE(BADFOVREFANGLE)" ); chkout_c ( "getangls_pdt" ); return; } gdpool_c ( keyword, 0, 1, &n, &locsec, &gotit ); /* Process locsec into the desired units: MILLIRADIANS. */ convrt_c ( locsec, locunit, "RADIANS", &locsec ); locsec = locsec*1000.0; /* At this point we have processed everything that is not shape specific. Perform shape specific actions. */ if ( eqstr_c ( locshap, "CIRCLE" ) == SPICETRUE ) { /* Convert the name of the shape to CIRCULAR. */ strncpy ( locshap, "CIRCULAR", shapelen ); /* Copy locsec to loccrs, since these angles are returned to the caller as identical in this case. */ loccrs = locsec; } else if ( eqstr_c ( locshap, "ELLIPSE" ) == SPICETRUE ) { /* Convert the name of the shape to ELLIPTICAL. */ strncpy ( locshap, "ELLIPTICAL", shapelen ); /* Fetch the FOV_CROSS_ANGLE. */ sprintf ( keyword, "INS%ld_FOV_CROSS_ANGLE", idcode ); dtpool_c ( keyword, &gotit, &n, &valtype ); if ( (n != 1) || (gotit == SPICEFALSE) || (valtype != 'N') ) { setmsg_c ( "The FOV cross angle for instrument # is " "missing or improperly defined. Check the " "kernels you are loading for " "INS#_FOV_CROSS_ANGLE." ); errch_c ( "#", name ); errint_c ( "#", idcode ); sigerr_c ( "SPICE(BADFOVCROSSANGLE)" ); chkout_c ( "getangls_pdt" ); return; } gdpool_c ( keyword, 0, 1, &n, &loccrs, &gotit ); /* Now convert it to the appropriate units. */ convrt_c ( loccrs, locunit, "RADIANS", &loccrs ); loccrs = loccrs*1000.0; } else if ( eqstr_c ( locshap, "RECTANGLE" ) == SPICETRUE ) { /* Convert the name of the shape to RECTANGULAR. */ strncpy ( locshap, "RECTANGULAR", shapelen ); /* Fetch the FOV_CROSS_ANGLE. */ sprintf ( keyword, "INS%ld_FOV_CROSS_ANGLE", idcode ); dtpool_c ( keyword, &gotit, &n, &valtype ); if ( (n != 1) || (gotit == SPICEFALSE) || (valtype != 'N') ) { setmsg_c ( "The FOV cross angle for instrument # is " "missing or improperly defined. Check the " "kernels you are loading for " "INS#_FOV_CROSS_ANGLE." ); errch_c ( "#", name ); errint_c ( "#", idcode ); sigerr_c ( "SPICE(BADFOVCROSSANGLE)" ); chkout_c ( "getangls_pdt" ); return; } gdpool_c ( keyword, 0, 1, &n, &loccrs, &gotit ); /* Now convert it to the appropriate units. */ convrt_c ( loccrs, locunit, "RADIANS", &loccrs ); loccrs = loccrs*1000.0; } /* If the value of SHAPE is something other than what we support, signal an error. */ else { setmsg_c ( "The shape, #, specified for the FOV of " "instrument #, is not currently supported." ); errch_c ( "#", locshap ); errch_c ( "#", name ); sigerr_c ( "SPICE(UNSUPPORTEDSHAPE)" ); chkout_c ( "getangls_pdt" ); return; } /* Now place the local copies of the results into the output arguments. */ *secang = locsec; *crsang = loccrs; /* Copy locshap into the shape argument safely. */ strncpy ( shape, locshap, shapelen-1 ); /* Pop the terminating null on the end of the expression. We do this to ensure that proper truncation occurs in the event that shape is not large enough to contain all of locshap. */ shape[shapelen-1] = '\0'; chkout_c ( "getangls_pdt" ); return; } /* End getangls_pdt */