PageRenderTime 47ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/src/ckr01.c

https://github.com/mattbornski/spice
C | 602 lines | 108 code | 160 blank | 334 comment | 19 complexity | f1b5205e88470c7aae19491120845fd3 MD5 | raw file
  1. /* ckr01.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. #include "f2c.h"
  6. /* Table of constant values */
  7. static integer c__2 = 2;
  8. static integer c__6 = 6;
  9. /* $Procedure CKR01 ( C-kernel, read pointing record, data type 1 ) */
  10. /* Subroutine */ int ckr01_(integer *handle, doublereal *descr, doublereal *
  11. sclkdp, doublereal *tol, logical *needav, doublereal *record, logical
  12. *found)
  13. {
  14. /* System generated locals */
  15. integer i__1, i__2;
  16. doublereal d__1;
  17. /* Builtin functions */
  18. integer s_rnge(char *, integer, char *, integer);
  19. /* Local variables */
  20. integer nrec, ndir, skip, psiz, i__, n;
  21. extern /* Subroutine */ int chkin_(char *, ftnlen), dafus_(doublereal *,
  22. integer *, integer *, doublereal *, integer *);
  23. integer group;
  24. extern /* Subroutine */ int dafgda_(integer *, integer *, integer *,
  25. doublereal *);
  26. doublereal buffer[100];
  27. integer remain, dirloc;
  28. extern integer lstcld_(doublereal *, integer *, doublereal *), lstled_(
  29. doublereal *, integer *, doublereal *);
  30. extern /* Subroutine */ int sigerr_(char *, ftnlen), chkout_(char *,
  31. ftnlen);
  32. integer grpndx;
  33. extern /* Subroutine */ int setmsg_(char *, ftnlen), errint_(char *,
  34. integer *, ftnlen);
  35. extern logical return_(void);
  36. doublereal dcd[2];
  37. integer beg, icd[6], end;
  38. logical fnd;
  39. /* $ Abstract */
  40. /* Read a pointing record from a CK segment, data type 1. */
  41. /* $ Disclaimer */
  42. /* THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
  43. /* CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
  44. /* GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
  45. /* ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
  46. /* PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
  47. /* TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
  48. /* WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
  49. /* PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
  50. /* SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
  51. /* SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */
  52. /* IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
  53. /* BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
  54. /* LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
  55. /* INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
  56. /* REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
  57. /* REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */
  58. /* RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
  59. /* THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
  60. /* CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
  61. /* ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */
  62. /* $ Required_Reading */
  63. /* CK */
  64. /* DAF */
  65. /* $ Keywords */
  66. /* POINTING */
  67. /* $ Declarations */
  68. /* $ Brief_I/O */
  69. /* Variable I/O Description */
  70. /* -------- --- -------------------------------------------------- */
  71. /* HANDLE I File handle. */
  72. /* DESCR I Segment descriptor. */
  73. /* SCLKDP I Spacecraft clock time. */
  74. /* TOL I Time tolerance. */
  75. /* NEEDAV I True when angular velocity data is requested. */
  76. /* RECORD O Pointing data record. */
  77. /* FOUND O True when data is found. */
  78. /* $ Detailed_Input */
  79. /* HANDLE is the integer handle of the CK file containing the */
  80. /* segment. */
  81. /* DESCR is the descriptor of the segment. */
  82. /* SCLKDP is an encoded spacecraft clock time for which */
  83. /* pointing is being requested. The SPICELIB routines */
  84. /* SCENCD and SCDECD are used to encode and decode SCLK */
  85. /* times. */
  86. /* TOL is a time tolerance, measured in the same units as */
  87. /* encoded spacecraft clock. */
  88. /* The record returned by CKR01 is the one whose time is */
  89. /* closest to SCLKDP and within TOL units of SCLKDP. */
  90. /* NEEDAV is true when angular velocity data is requested. */
  91. /* $ Detailed_Output */
  92. /* RECORD is the pointing record. Contents are as follows: */
  93. /* RECORD( 1 ) = CLKOUT */
  94. /* RECORD( 2 ) = q0 */
  95. /* RECORD( 3 ) = q1 */
  96. /* RECORD( 4 ) = q2 */
  97. /* RECORD( 5 ) = q3 */
  98. /* RECORD( 6 ) = Av1 ] */
  99. /* RECORD( 7 ) = Av2 |-- Returned optionally */
  100. /* RECORD( 8 ) = Av3 ] */
  101. /* CLKOUT is the encoded spacecraft clock time for the */
  102. /* returned pointing values. CLKOUT will be the closest */
  103. /* time in the segment to the input time as long as it is */
  104. /* within the input tolerance (see FOUND below). If SCLKDP */
  105. /* falls at the exact midpoint of two times, the record */
  106. /* for the greater of the two will be returned. */
  107. /* The quantities q0 - q3 represent a quaternion. */
  108. /* The quantities Av1, Av2, and Av3 represent the angular */
  109. /* velocity vector, and are returned if the segment */
  110. /* contains angular velocity data and NEEDAV is true. */
  111. /* The components of the angular velocity vector are */
  112. /* specified relative to the inertial reference frame */
  113. /* for the segment. */
  114. /* FOUND is true if a record was found to satisfy the pointing */
  115. /* request. FOUND will be false when there is no pointing */
  116. /* instance within the segment whose time falls within */
  117. /* the requested time tolerance on either side of the */
  118. /* input time. */
  119. /* $ Parameters */
  120. /* None. */
  121. /* $ Exceptions */
  122. /* 1) If the specified handle does not belong to any file that is */
  123. /* currently known to be open, an error is diagnosed by a */
  124. /* routine that this routine calls. */
  125. /* 2) If DESCR is not a valid, packed descriptor of a segment in */
  126. /* the CK file specified by HANDLE, the results of this routine */
  127. /* are unpredictable. */
  128. /* 3) If the segment is not of data type 1, as specified in the */
  129. /* third integer component of the segment descriptor, then */
  130. /* the error SPICE(WRONGDATATYPE) is signalled. */
  131. /* 4) If there is a need for angular velocity data and the segment */
  132. /* contains no such data, the error SPICE(NOAVDATA) is signalled. */
  133. /* $ Files */
  134. /* The file containing the segment is specified by its handle, and */
  135. /* should be opened for read, either by CKLPF or DAFOPR. */
  136. /* $ Particulars */
  137. /* See the CK Required Reading file for a detailed description of */
  138. /* the structure of a type 1 pointing segment. */
  139. /* This routine searches a type 1 segment for the pointing instance */
  140. /* whose associated time is closest to the time that pointing was */
  141. /* requested for. If this time is within the tolerance specified by */
  142. /* the user, it sets FOUND equal to true and returns information in */
  143. /* the array RECORD that CKE01 uses to evaluate the pointing at the */
  144. /* time CLKOUT. */
  145. /* $ Examples */
  146. /* The CKRnn routines are usually used in tandem with the CKEnn */
  147. /* routines, which evaluate the record returned by CKRnn to give */
  148. /* the pointing information and output time. */
  149. /* The following code fragment searches through a file (represented */
  150. /* by HANDLE) for all segments applicable to the Voyager 2 wide angle */
  151. /* camera, for a particular spacecraft clock time, which have data */
  152. /* type 1. It then evaluates the pointing for that epoch and prints */
  153. /* the result. */
  154. /* C */
  155. /* C - Get the spacecraft clock time. Must encode it for use */
  156. /* C in the C-kernel. */
  157. /* C */
  158. /* C - Set the time tolerance high to catch anything close to */
  159. /* C the input time. */
  160. /* C */
  161. /* C - We don't need angular velocity data. */
  162. /* C */
  163. /* SC = -32 */
  164. /* INST = -32002 */
  165. /* TOL = 1000.D0 */
  166. /* NEEDAV = .FALSE. */
  167. /* DTYPE = 1 */
  168. /* C */
  169. /* C Load the Voyager 2 spacecraft clock kernel and the C-kernel. */
  170. /* C */
  171. /* CALL FURNSH ( 'VGR_SCLK.TSC' ) */
  172. /* CALL DAFOPR ( 'VGR2_CK.BC', HANDLE ) */
  173. /* C */
  174. /* C Convert the input request time to ticks. */
  175. /* C */
  176. /* WRITE (*,*) 'Enter spacecraft clock time string:' */
  177. /* READ (*,FMT='(A)') SCLKCH */
  178. /* CALL SCENCD ( SC, SCLKCH, SCLKDP ) */
  179. /* C */
  180. /* C Search from the beginning through all segments. */
  181. /* C */
  182. /* CALL DAFBFS ( HANDLE ) */
  183. /* CALL DAFFNA ( SFND ) */
  184. /* DO WHILE ( SFND ) */
  185. /* CALL DAFGN ( IDENT ) */
  186. /* CALL DAFGS ( DESCR ) */
  187. /* CALL DAFUS ( DESCR, 2, 6, DCD, ICD ) */
  188. /* IF ( INST .EQ. ICD( 1 ) .AND. */
  189. /* . DTYPE .EQ. ICD( 3 ) .AND. */
  190. /* . SCLKDP + TOL .GE. DCD( 1 ) .AND. */
  191. /* . SCLKDP - TOL .LE. DCD( 2 ) ) THEN */
  192. /* CALL CKR01 ( HANDLE, DESCR, SCLKDP, TOL, NEEDAV, */
  193. /* . RECORD, FOUND ) */
  194. /* IF ( FOUND ) THEN */
  195. /* CALL CKE01 ( NEEDAV, RECORD, CMAT, AV, CLKOUT ) */
  196. /* WRITE (*,*) 'Segment descriptor and identifier:' */
  197. /* WRITE (*,*) DCD, ICD */
  198. /* WRITE (*,*) IDENT */
  199. /* WRITE (*,*) 'C-matrix:' */
  200. /* WRITE (*,*) CMAT */
  201. /* END IF */
  202. /* END IF */
  203. /* CALL DAFFNA ( SFND ) */
  204. /* END DO */
  205. /* $ Restrictions */
  206. /* 1) The file containing the segment should be opened for read, */
  207. /* either by CKLPF or DAFOPR. */
  208. /* $ Literature_References */
  209. /* None. */
  210. /* $ Author_and_Institution */
  211. /* J.M. Lynch (JPL) */
  212. /* J.E. McLean (JPL) */
  213. /* M.J. Spencer (JPL) */
  214. /* R.E. Thurman (JPL) */
  215. /* I.M. Underwood (JPL) */
  216. /* $ Version */
  217. /* - SPICELIB Version 1.2.1, 22-AUG-2006 (EDW) */
  218. /* Replaced references to LDPOOL with references */
  219. /* to FURNSH. */
  220. /* - SPICELIB Version 1.2.0, 07-SEP-2001 (EDW) */
  221. /* Replaced DAFRDA call with DAFGDA. */
  222. /* Added IMPLICIT NONE. */
  223. /* - SPICELIB Version 1.1.1, 10-MAR-1992 (WLT) */
  224. /* Comment section for permuted index source lines was added */
  225. /* following the header. */
  226. /* - SPICELIB Version 1.1.0, 30-AUG-1991 (JML) */
  227. /* This routine now checks the segment descriptor to */
  228. /* determine if it has been given a type 1 segment. */
  229. /* The FOUND flag is set to FALSE at the beginning of */
  230. /* the routine. */
  231. /* The particulars section was changed to provide a more */
  232. /* general description of the function of this routine. The */
  233. /* information that was originally in Particulars was moved */
  234. /* to the body of the code. */
  235. /* The example program was changed so that the tolerance */
  236. /* and data type are used in selecting which segments to read. */
  237. /* - SPICELIB Version 1.0.1, 02-NOV-1990 (JML) */
  238. /* The example program was corrected so that the input */
  239. /* instrument code was tested against ICD(1) instead of */
  240. /* ICD(3). */
  241. /* - SPICELIB Version 1.0.0, 07-SEP-1990 (RET) (IMU) */
  242. /* -& */
  243. /* $ Index_Entries */
  244. /* read ck type_1 pointing data record */
  245. /* -& */
  246. /* $ Revisions */
  247. /* - SPICELIB Version 2.0.0, 30-AUG-1991 (JML) */
  248. /* 1) This routine now checks the segment descriptor, ICD(3), */
  249. /* to determine if it has been given a type 1 segment. */
  250. /* 2) The FOUND flag is set to FALSE at the beginning of */
  251. /* the routine. This is done so that if a SPICE error */
  252. /* is signalled, the FOUND flag will definitely be false. */
  253. /* 3) The particulars section was changed to provide a more */
  254. /* general description of the function of this routine. The */
  255. /* information that was originally in Particulars was moved */
  256. /* to the body of the code. */
  257. /* 4) The example program was changed so that the tolerance */
  258. /* and data type are used in selecting which segments to read. */
  259. /* - SPICELIB Version 1.0.1, 02-NOV-1990 (JML) */
  260. /* 1) The example program was corrected so that the input */
  261. /* instrument code was tested against ICD(1) instead of */
  262. /* ICD(3). */
  263. /* 2) ROTATIONS was removed from the Required Reading section. */
  264. /* - Beta Version 1.1.0, 29-AUG-1990 (MJS) (JEM) */
  265. /* The following changes were made as a result of the */
  266. /* NAIF CK Code and Documentation Review: */
  267. /* 1) The variable SCLK was changed to SCLKDP. */
  268. /* 2) The declarations for the parameters QSIZ, QAVSIZ, NDC, and */
  269. /* NIC were moved from the "Declarations" section of the */
  270. /* header to the "Local parameters" section of the code below */
  271. /* the header. These parameters are not meant to modified by */
  272. /* users. */
  273. /* 3) The variable DIRSIZ has been parameterized in the code */
  274. /* following the header. DIRSIZ is still 100. */
  275. /* 5) The header was improved and updated to reflect the changes. */
  276. /* 6) The in-code comments were improved. */
  277. /* - Beta Version 1.0.0, 17-MAY-1990 (RET) (IMU) */
  278. /* -& */
  279. /* SPICELIB functions */
  280. /* Local parameters */
  281. /* DIRSIZ is the directory size. */
  282. /* NDC is the number of double precision components in an */
  283. /* unpacked C-kernel segment descriptor. */
  284. /* NIC is the number of integer components in an unpacked */
  285. /* C-kernel segment descriptor. */
  286. /* QSIZ is the number of double precision numbers making up */
  287. /* the quaternion portion of a pointing record. */
  288. /* QAVSIZ is the number of double precision numbers making up */
  289. /* the quaternion and angular velocity portion of a */
  290. /* pointing record. */
  291. /* DTYPE is the data type of the segment that this routine */
  292. /* operates on. */
  293. /* Local variables */
  294. /* Standard SPICE error handling. */
  295. if (return_()) {
  296. return 0;
  297. } else {
  298. chkin_("CKR01", (ftnlen)5);
  299. }
  300. /* To minimize the number of file reads performed during the search, */
  301. /* a buffer of 100 double precision numbers is used to read the SCLK */
  302. /* times from the C-kernel. If there are 10,001 or fewer pointing */
  303. /* records, at most four reads will be needed to satisfy the request: */
  304. /* one to read NREC, one to read in 100 or fewer directory times, */
  305. /* one to read 100 or fewer actual times, and then after the */
  306. /* appropriate record has been located, one to read the quaternion */
  307. /* and angular velocity data. */
  308. /* One more read would be required for every other group of 10,000 */
  309. /* records in the segment. */
  310. /* Start off with FOUND set to FALSE. */
  311. *found = FALSE_;
  312. /* We need to look at a few of the descriptor components. */
  313. /* The unpacked descriptor contains the following information */
  314. /* about the segment: */
  315. /* DCD(1) Initial encoded SCLK */
  316. /* DCD(2) Final encoded SCLK */
  317. /* ICD(1) Instrument */
  318. /* ICD(2) Inertial reference frame */
  319. /* ICD(3) Data type */
  320. /* ICD(4) Angular velocity flag */
  321. /* ICD(5) Initial address of segment data */
  322. /* ICD(6) Final address of segment data */
  323. dafus_(descr, &c__2, &c__6, dcd, icd);
  324. /* Check to make sure that the segment is type 1. */
  325. if (icd[2] != 1) {
  326. setmsg_("The segment is not a type 1 segment. Type is #", (ftnlen)47)
  327. ;
  328. errint_("#", &icd[2], (ftnlen)1);
  329. sigerr_("SPICE(WRONGDATATYPE)", (ftnlen)20);
  330. chkout_("CKR01", (ftnlen)5);
  331. return 0;
  332. }
  333. /* The size of the record returned depends on whether or not the */
  334. /* segment contains angular velocity data. */
  335. /* This is a convenient place to check if the need for angular */
  336. /* velocity data matches the availability. */
  337. if (icd[3] == 1) {
  338. psiz = 7;
  339. } else {
  340. psiz = 4;
  341. if (*needav) {
  342. setmsg_("Segment does not contain angular velocity data.", (
  343. ftnlen)47);
  344. sigerr_("SPICE(NOAVDATA)", (ftnlen)15);
  345. chkout_("CKR01", (ftnlen)5);
  346. return 0;
  347. }
  348. }
  349. /* The beginning and ending addresses of the segment are in the */
  350. /* descriptor. */
  351. beg = icd[4];
  352. end = icd[5];
  353. /* Get the number of records in this segment, and from that determine */
  354. /* the number of directory epochs. */
  355. dafgda_(handle, &end, &end, buffer);
  356. nrec = (integer) buffer[0];
  357. ndir = (nrec - 1) / 100;
  358. /* The directory epochs narrow down the search to a group of DIRSIZ */
  359. /* or fewer records. The way the directory is constructed guarantees */
  360. /* that we will definitely find the closest time in the segment to */
  361. /* SCLKDP in the indicated group. */
  362. /* There is only one group if there are no directory epochs. */
  363. if (ndir == 0) {
  364. group = 1;
  365. } else {
  366. /* Compute the location of the first directory epoch. From the */
  367. /* beginning of the segment, need to go through all of the */
  368. /* pointing numbers (PSIZ*NREC of them), then through all of */
  369. /* the SCLKDP times (NREC more) to get to the first SCLK */
  370. /* directory. */
  371. dirloc = beg + (psiz + 1) * nrec;
  372. /* Locate the first directory epoch greater than SCLKDP. Read in */
  373. /* as many as DIRSIZ directory epochs at a time for comparison. */
  374. fnd = FALSE_;
  375. remain = ndir;
  376. group = 0;
  377. while(! fnd) {
  378. /* The number of records to read in the buffer. */
  379. n = min(remain,100);
  380. i__1 = dirloc + n - 1;
  381. dafgda_(handle, &dirloc, &i__1, buffer);
  382. remain -= n;
  383. /* If we find the first directory time greater than or equal */
  384. /* to the epoch, we're done. */
  385. /* If we reach the end of the directories, and still haven't */
  386. /* found one bigger than the epoch, the group is the last group */
  387. /* in the segment. */
  388. /* Otherwise keep looking. */
  389. i__ = lstled_(sclkdp, &n, buffer);
  390. if (i__ < n) {
  391. group = group + i__ + 1;
  392. fnd = TRUE_;
  393. } else if (remain == 0) {
  394. group = ndir + 1;
  395. fnd = TRUE_;
  396. } else {
  397. dirloc += n;
  398. group += n;
  399. }
  400. }
  401. }
  402. /* Now we know which group of DIRSIZ (or less) times to look at. */
  403. /* Out of the NREC SCLKDP times, the number that we should skip over */
  404. /* to get to the proper group is DIRSIZ*( GROUP - 1 ). */
  405. skip = (group - 1) * 100;
  406. /* From this we can compute the index into the segment of the group */
  407. /* of times we want. From the beginning, need to pass through */
  408. /* PSIZ*NREC pointing numbers to get to the first SCLKDP time. */
  409. /* Then we skip over the number just computed above. */
  410. grpndx = beg + nrec * psiz + skip;
  411. /* The number of times that we have to look at may be less than */
  412. /* DIRSIZ. However many there are, go ahead and read them into the */
  413. /* buffer. */
  414. /* Computing MIN */
  415. i__1 = 100, i__2 = nrec - skip;
  416. n = min(i__1,i__2);
  417. i__1 = grpndx + n - 1;
  418. dafgda_(handle, &grpndx, &i__1, buffer);
  419. /* Find the time in the group closest to the input time, and see */
  420. /* if it's within tolerance. */
  421. i__ = lstcld_(sclkdp, &n, buffer);
  422. if ((d__1 = *sclkdp - buffer[(i__1 = i__ - 1) < 100 && 0 <= i__1 ? i__1 :
  423. s_rnge("buffer", i__1, "ckr01_", (ftnlen)625)], abs(d__1)) > *tol)
  424. {
  425. chkout_("CKR01", (ftnlen)5);
  426. return 0;
  427. }
  428. /* Now we know the exact record that we want. */
  429. /* RECORD( 1 ) holds CLKOUT. */
  430. *found = TRUE_;
  431. record[0] = buffer[(i__1 = i__ - 1) < 100 && 0 <= i__1 ? i__1 : s_rnge(
  432. "buffer", i__1, "ckr01_", (ftnlen)638)];
  433. /* We need the Ith pointing record out of this group of DIRSIZ. */
  434. /* This group of DIRSIZ is SKIP records into the beginning */
  435. /* of the segment. And each record is PSIZ big. */
  436. n = beg + psiz * (skip + i__ - 1);
  437. i__1 = n + psiz - 1;
  438. dafgda_(handle, &n, &i__1, &record[1]);
  439. /* That is all. */
  440. chkout_("CKR01", (ftnlen)5);
  441. return 0;
  442. } /* ckr01_ */