Skip to content

Commit f48d801

Browse files
committed
Gap-fill option for missing spice data
1 parent 9a26ada commit f48d801

File tree

1 file changed

+62
-7
lines changed

1 file changed

+62
-7
lines changed

utilities/das3_spice.c

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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 */
328336
typedef 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

Comments
 (0)