@@ -68,9 +68,9 @@ void prnHelp()
6868" coordinates on standard input, modifies values and structures using SPICE\n"
6969" information, and writes a das3 stream to standard output.\n"
7070"\n"
71- " A SPICE meta-kernel file is always required as a parameter. Multiple \n"
72- " may be provide so long as each separated by a comma and the filenames \n"
73- " themselves contain no commas.\n"
71+ " One or more SPICE meta-kernel files are always required as a parameter.\n"
72+ " Multiple may be provide so long as each is separated by a comma and the\n"
73+ " filenames themselves contain no commas.\n"
7474"\n"
7575" In addition to the kernel argument, at least one SPICE operation must\n"
7676" be provided on the command line. Three types of operations are supported:\n"
@@ -186,14 +186,20 @@ void prnHelp()
186186" output stream, but this option may be used to preserve the\n"
187187" original vectors alongside the rotated items.\n"
188188"\n"
189+ " -g, --gap-fill\n"
190+ " By default, SPICE coverage gaps result in " PROG " exiting\n"
191+ " with an error return. Use this option to output fill values\n"
192+ " for regions where spice kernels are incomplete. NOTE: Coverage\n"
193+ " gap detection and recovery may slow processing.\n"
194+ "\n"
189195" -p [TYPE:]NAME=VALUE, --prop [TYPE:]NAME=VALUE\n"
190196" Add property NAME to the output stream header of the given TYPE\n"
191197" with the given VALUE. If TYPE is missing, it defaults to\n"
192198" \"string\". See the dasStream 3.0 definition document for\n"
193199" details.\n"
194200"\n"
195201" -I, --info An information option. Just print all frames defined in the\n"
196- " given meta-kernel to the standard error channel and exit.\n"
202+ " given meta-kernels to the standard error channel and exit.\n"
197203"\n"
198204" -L [BODY:]OUT_FRAME[,SYSTEM], --locate=BODY:OUT_FRAME[,SYSTEM]\n"
199205" Add location data to the stream for the given BODY in the\n"
@@ -315,14 +321,16 @@ typedef struct xform_request {
315321 char aOutCenter [DASFRM_NAME_SZ ];/* Name for central body of the output frame */
316322 ubyte uOutSystem ; /* See definitions in DasFrame.h */
317323 ubyte uOutDasId ; /* ID used with dasStream to link vectors & frames */
324+ bool bGapFill ; /* Use fill data when SPICE gaps are encountered */
325+ int nGapRecs ; /* Number of gap records encountered */
318326
319327 /* The coordinates to output. The order is:
320328 x,y,z - For cartesian coords
321329 ρ,φ,z - For cylindrical cords
322330 r,θ,φ - For spherical coords */
323331 bool aOutCoords [3 ]; /* Default to all three for now */
324332
325- } XReq ;
333+ } XReq ;
326334
327335/* Owned by output DasVar structs. Generated on new Dataset Definition */
328336typedef struct xform_calc {
@@ -344,6 +352,7 @@ typedef struct context{
344352 bool bKeepOrig ; /* Keep original vectiors in datasets */
345353 bool bHasMatchAny ; /* We're trying to match any in-frame */
346354 bool bWantsLocs ; /* We want to output at least one location */
355+ bool bGapFill ; /* Output fill data for SPICE gaps, don't fail */
347356
348357 char aLevel [32 ]; /* Log level */
349358 char aMetaKern [256 ]; /* The metakernel file name */
@@ -369,7 +378,7 @@ typedef struct context{
369378#define CAR_Z 2
370379 / * Coordinate names below follow ISO 31-11:1992 std * /
371380#define CYL_RHO 0 / * Normal from axis for cylinders * /
372- #define CYL_PHI 1 / * longitude angle * /
381+ #define CYL_PHI 1 / * longitude angle * /
373382#define CYL_Z 2 / * Along axis for cyliders * /
374383
375384#define SPH_R 0 / * Radial from center point for spheres * /
@@ -479,6 +488,10 @@ int parseArgs(int argc, char** argv, Context* pCtx)
479488 pCtx -> bDataOnly = true;
480489 continue ;
481490 }
491+ if (dascmd_isArg (argv [i ], "-g" , "--gap-fill" , NULL )){
492+ pCtx -> bGapFill = true;
493+ continue ;
494+ }
482495 if (dascmd_isArg (argv [i ], "-k" , "--keep" , NULL )){
483496 pCtx -> bKeepOrig = true;
484497 continue ;
@@ -568,6 +581,14 @@ int parseArgs(int argc, char** argv, Context* pCtx)
568581 pCtx -> uFlushSz = ((size_t )fMemUse ) * 1048576ull ;
569582 }
570583 }
584+
585+ /* Copy in global settings to individual requests if any */
586+ if (pCtx -> bGapFill ){
587+ for (size_t iReq = 0 ; iReq < pCtx -> nXReq ; ++ iReq ){
588+ pCtx -> aXReq [iReq ].bGapFill = true;
589+ pCtx -> aXReq [iReq ].nGapRecs = 0 ;
590+ }
591+ }
571592
572593 return DAS_OKAY ;
573594}
@@ -1476,6 +1497,7 @@ DasErrCode _writeLocation(DasDs* pDsIn, XCalc* pCalc, double rTimeShift)
14761497 SpiceDouble aRecOut [3 ];
14771498 SpiceDouble aTmp [3 ];
14781499 SpiceInt nTmp ;
1500+ char sUtc [36 ];
14791501 float aOutput [3 ];
14801502
14811503 DasAry * pAryOut = DasVar_getArray (pCalc -> pVarOut );
@@ -1488,7 +1510,7 @@ DasErrCode _writeLocation(DasDs* pDsIn, XCalc* pCalc, double rTimeShift)
14881510 SpiceDouble radOut = 0.0 ; /* Potential constants for ellipsoidal coords */
14891511 SpiceDouble flatOut = 0.0 ;
14901512 if ((uSysOut == DAS_VSYS_DETIC )|| (uSysOut == DAS_VSYS_GRAPHIC )){
1491- bodvcd_c (pReq -> nBodyId , "RADII" , 3 , & nTmp , aTmp );
1513+ bodvcd_c (pReq -> nOutCenter , "RADII" , 3 , & nTmp , aTmp );
14921514 radOut = aTmp [0 ];
14931515 flatOut = (radOut - aTmp [0 ]) / radOut ;
14941516 }
@@ -1504,6 +1526,22 @@ DasErrCode _writeLocation(DasDs* pDsIn, XCalc* pCalc, double rTimeShift)
15041526 spkezp_c (
15051527 pReq -> nBodyId , rEt , pReq -> aOutFrame , "NONE" , pReq -> nOutCenter , aRecOut , & rLt
15061528 );
1529+ if (pReq -> bGapFill && failed_c ()){
1530+ DasAry_append (pAryOut , NULL , 3 ); /* <-- assumes all 3 normally output */
1531+ reset_c ();
1532+ if (pReq -> bGapFill ){
1533+ if (pReq -> nGapRecs == 0 ){
1534+ memset (sUtc , 0 , 36 );
1535+ et2utc_c (rEt , "ISOC" , 3 , 32 , sUtc );
1536+ daslog_warn_v (
1537+ "SPICE coverage gap detected for %s in frame %s at %s, using fill (-g)." ,
1538+ pReq -> aBody , pReq -> aOutFrame , sUtc
1539+ );
1540+ }
1541+ ++ (pReq -> nGapRecs );
1542+ }
1543+ continue ;
1544+ }
15071545
15081546 if (uSysOut != DAS_VSYS_CART ){ /* Convert output coord sys if needed */
15091547 switch (uSysOut ){
@@ -1579,6 +1617,7 @@ DasErrCode _writeRotation(DasDs* pDsIn, XCalc* pCalc, double rTimeShift)
15791617 float aOutput [3 ];
15801618 ubyte uSysOut = 0 ;
15811619 das_geovec * pVecIn = NULL ;
1620+ char sUtc [36 ];
15821621
15831622 DasAry * pAryOut = DasVar_getArray (pCalc -> pVarOut );
15841623 if (pAryOut == NULL )
@@ -1600,6 +1639,22 @@ DasErrCode _writeRotation(DasDs* pDsIn, XCalc* pCalc, double rTimeShift)
16001639 rEt = _dm2et (& dm , rTimeShift );
16011640
16021641 pxform_c (pReq -> aInFrame , pReq -> aOutFrame , rEt , mRot ); /* Get rot matrix */
1642+ if (pReq -> bGapFill && failed_c ()){
1643+ DasAry_append (pAryOut , NULL , 3 );
1644+ reset_c ();
1645+ if (pReq -> bGapFill ){
1646+ if (pReq -> nGapRecs == 0 ){
1647+ memset (sUtc , 0 , 36 );
1648+ et2utc_c (rEt , "ISOC" , 3 , 32 , sUtc );
1649+ daslog_warn_v (
1650+ "SPICE coverage gap detected for frame %s at %s, using fill (-g)." ,
1651+ pReq -> aOutFrame , sUtc
1652+ );
1653+ }
1654+ ++ (pReq -> nGapRecs );
1655+ }
1656+ continue ;
1657+ }
16031658
16041659 DasVar_get (pVarIn , iter .index , & dm );
16051660
0 commit comments