From 298663b5c7a6875c306fcd66d9d3cd3e13bb0b8b Mon Sep 17 00:00:00 2001 From: Chris Piker Date: Mon, 7 Oct 2024 23:53:23 -0500 Subject: [PATCH] Bug fix in vector var encoding --- das2/var_ary.c | 68 ++++++++++++++++++++++++++++-------------- das2/var_base.c | 32 ++++++++++++++++++++ das2/vector.c | 4 +-- test/tag_test.dNt | 4 +-- utilities/das3_spice.c | 37 +++++++++++++++-------- 5 files changed, 107 insertions(+), 38 deletions(-) diff --git a/das2/var_ary.c b/das2/var_ary.c index d610280..2f85f19 100644 --- a/das2/var_ary.c +++ b/das2/var_ary.c @@ -35,6 +35,7 @@ char* _DasVar_prnIntr( const DasVar* pThis, const char* sFrame, ubyte* pFrmDirs, ubyte nFrmDirs, char* sBuf, int nBufLen ); +void _DasVar_copyTo(const DasVar* pThis, DasVar* pOther); DasStream* _DasVar_getStream(const DasVar* pThis); @@ -64,6 +65,21 @@ typedef struct das_var_vecary{ } DasVarVecAry; +void _DasVarAry_copyTo(const DasVarAry* pThis, DasVarAry* pOther) +{ + _DasVar_copyTo((const DasVar*)pThis, (DasVar*)pOther); + + /* Add in my stuff, but don't copy the bulk data array, just bump + the reference count */ + if(pThis->pAry != NULL){ + pOther->pAry = pThis->pAry; + inc_DasAry( pOther->pAry ); + } + + memcpy(pOther->idxmap, pThis->idxmap, DASIDX_MAX*sizeof(int)); + pOther->varsubtype = pThis->varsubtype; +} + DasVar* copy_DasVarAry(const DasVar* pBase){ /* Why no run-time type checking here? This function is only visible inside this module, and it's assigned @@ -72,12 +88,17 @@ DasVar* copy_DasVarAry(const DasVar* pBase){ match the function. */ assert(pBase->vartype == D2V_ARRAY); - DasVar* pRet = calloc(1, sizeof(DasVarAry)); - memcpy(pRet, pBase, sizeof(DasVarAry)); + /* Can't do direct memcpy, this would end up with two independent copies of + + DasVarVecAry.base.base.base.properties.pIdx0 + + pointing to the same das_idx_info structure. Handle it as a maunal copy + */ + + DasVarAry* pRet = calloc(1, sizeof(DasVarAry)); /* Make something of my size */ + _DasVarAry_copyTo((const DasVarAry*)pBase, pRet); /* Initialize it */ - if(((DasVarAry*)pBase)->pAry != NULL) - inc_DasAry( ((DasVarAry*)pBase)->pAry ); - return pRet; + return (DasVar*)pRet; } das_val_type DasVarAry_elemType(const DasVar* pBase){ @@ -988,16 +1009,18 @@ DasVar* new_DasVarAry(DasAry* pAry, int nExtRank, int8_t* pExtMap, int nIntIdx) DasVar* copy_DasVarVecAry(const DasVar* pAncestor) { - DasVarAry* pBase = (DasVarAry*)pAncestor; + const DasVarAry* pBase = (DasVarAry*)pAncestor; assert(pAncestor->vartype == D2V_ARRAY); /* Okay to not be present in release code */ assert(pBase->varsubtype == D2V_GEOVEC); - DasVar* pRet = calloc(1, sizeof(DasVarVecAry)); - memcpy(pRet, pBase, sizeof(DasVarVecAry)); - if(pBase->pAry != NULL) - inc_DasAry( pBase->pAry ); - return pRet; + DasVarVecAry* pRet = calloc(1, sizeof(DasVarVecAry)); /* Make something my size */ + _DasVarAry_copyTo(pBase, (DasVarAry*)pRet); /* Fill it with base class stuff */ + + DasVarVecAry* pThis = (DasVarVecAry*)pBase; /* Now add my stuff */ + pRet->tplt = pThis->tplt; + + return (DasVar*)pRet; } int DasVarAry_getFrame(const DasVar* pBase) @@ -1239,31 +1262,32 @@ DasErrCode DasVarAry_encode(DasVar* pBase, const char* sRole, DasBuf* pBuf) const char* sStorage = vtAry == vtTime ? "struct" : das_vt_toStr(vtAry); const char* sType = (pThis->varsubtype == D2V_GEOVEC) ? "vector" : "scalar"; + + char aComponents[32] = {'\0'}; + DasVarVecAry* pDerived = (DasVarVecAry*)pThis; + das_geovec gvec = pDerived->tplt; + if(pThis->varsubtype == D2V_GEOVEC){ + snprintf(aComponents, 32, "components=\"%hhu\" ", gvec.ncomp); + } DasBuf_printf(pBuf, - " <%s use=\"%s\" semantic=\"%s\" storage=\"%s\" index=\"%s\" units=\"%s\"", - sType, sRole, pBase->semantic, sStorage, sIndex, units + " <%s %suse=\"%s\" semantic=\"%s\" storage=\"%s\" index=\"%s\" units=\"%s\"", + sType, aComponents, sRole, pBase->semantic, sStorage, sIndex, units ); if(pThis->varsubtype == D2V_GEOVEC){ - DasVarVecAry* pDerived = (DasVarVecAry*)pThis; - das_geovec gvec = pDerived->tplt; - DasBuf_printf(pBuf, " system=\"%s\" ", das_compsys_str(gvec.systype)); if(das_geovec_hasRefSurf(&gvec)){ DasBuf_printf(pBuf, " surface=\"%hhu\"", das_geovec_surfId(&gvec)); } - else{ - DasBuf_puts(pBuf, ">\n"); - } - DasBuf_puts(pBuf, "components=\""); + DasBuf_puts(pBuf, "sysorder=\""); for(int i = 0; i < gvec.ncomp; ++i){ if(i> 0)DasBuf_puts(pBuf, ";"); DasBuf_printf(pBuf, "%d", das_geovec_dir(&gvec, i)); } - DasBuf_puts(pBuf, "\"/>"); + DasBuf_puts(pBuf, "\"/>\n"); nItems *= gvec.ncomp; /* More items per packet if we have vectors */ @@ -1280,7 +1304,7 @@ DasErrCode DasVarAry_encode(DasVar* pBase, const char* sRole, DasBuf* pBuf) /* 4. Write any properties, make sure a generic summary is included */ if(DasDesc_length((DasDesc*)pBase) > 0){ - int nRet = DasDesc_encode3((DasDesc*)pBase, pBuf, " "); + int nRet = DasDesc_encode3((DasDesc*)pBase, pBuf, " "); if(nRet != DAS_OKAY) return nRet; } diff --git a/das2/var_base.c b/das2/var_base.c index acaa300..2fb2ec5 100644 --- a/das2/var_base.c +++ b/das2/var_base.c @@ -127,6 +127,38 @@ DasErrCode DasVar_setSemantic(DasVar* pThis, const char* sSemantic) /* Pure virtual */ DasVar* copy_DasVar(const DasVar* pThis){ return pThis->copy(pThis); } +/* A copy helper for derived classes */ +void _DasVar_copyTo(const DasVar* pThis, DasVar* pOther) +{ + DasDesc_init((DasDesc*)pOther, VARIABLE); + DasDesc_copyIn((DasDesc*)pOther, (const DasDesc*)pThis); + + pOther->vartype = pThis->vartype; + pOther->vt = pThis->vt; + pOther->vsize = pThis->vsize; + memcpy(pOther->semantic, pThis->semantic, D2V_MAX_SEM_LEN); + pOther->nExtRank = pThis->nExtRank; + pOther->nIntRank = pThis->nIntRank; + pOther->units = pThis->units; + pOther->nRef = 1; + + pOther->id = pThis->id; + pOther->elemType = pThis->elemType; + pOther->shape = pThis->shape; + pOther->intrShape = pThis->intrShape; + pOther->expression = pThis->expression; + pOther->lengthIn = pThis->lengthIn; + pOther->get = pThis->get; + pOther->isFill = pThis->isFill; + pOther->isNumeric = pThis->isNumeric; + pOther->subset = pThis->subset; + pOther->incRef = pThis->incRef; + pOther->copy = pThis->copy; + pOther->decRef = pThis->decRef; + pOther->degenerate = pThis->degenerate; + pOther->pUser = NULL; /* Do not copy over the user data pointer */ +} + das_val_type DasVar_elemType(const DasVar* pThis){ return pThis->elemType(pThis); } diff --git a/das2/vector.c b/das2/vector.c index 206292a..515f658 100644 --- a/das2/vector.c +++ b/das2/vector.c @@ -109,7 +109,7 @@ const char* das_compsys_desc(ubyte uST) switch(uST & 0xF){ case DAS_VSYS_CART: return "A standard orthoginal coordiante system. The full component set " - "is (x,y,z). Missing components are assumed to be 0."; + "is (x,y,z). Missing components are assumed to be 0."; case DAS_VSYS_CYL: return "An ISO 31-11 standard cylindrical system. The full componet set " "is (ρ,ϕ,z) where ρ is distance to the z-axis, φ is eastward " @@ -246,7 +246,7 @@ DAS_API int das_geovec_dir(const das_geovec* pThis, int i) { if((i < 0)||(i > pThis->ncomp)) return -1*das_error(DASERR_VEC, "Invalid vector component index"); - return (pThis->dirs >> (2*(pThis->ncomp))) & 0x3; + return (pThis->dirs >> (2*i)) & 0x3; } int das_geovec_dirs(const das_geovec* pThis, ubyte* pDirs) diff --git a/test/tag_test.dNt b/test/tag_test.dNt index 854e414..b8718f5 100644 --- a/test/tag_test.dNt +++ b/test/tag_test.dNt @@ -1,4 +1,4 @@ -|Sx||862| +|Sx||859|

Magnetic Field Components in the Lab Frame from VMRS

@@ -9,7 +9,7 @@

(1.0 minute Averages)

das2_bin_avgsec

- +

Room 601 Coordinates

diff --git a/utilities/das3_spice.c b/utilities/das3_spice.c index 4e69524..9e19b57 100644 --- a/utilities/das3_spice.c +++ b/utilities/das3_spice.c @@ -852,16 +852,24 @@ DasErrCode _addRotation(XCalc* pCalc, const char* sAnonFrame, DasDs* pDsOut) int nDsRank = DasDs_shape(pDsOut, aDsShape); XReq* pReq = &(pCalc->request); - /* If this rotation has no specified input frame, and we have an anonymous - frame definition, use that */ + /* If this rotation has no specified input frame, then set our frame as + the input frame. If we don't have one, fall back to the anonymous + frame, if specified */ if(pReq->aInFrame[0] == '\0'){ - if(sAnonFrame[0] == '\0'){ - return das_error(PERR, - "Can not add rotation operation, input frame not specified " - "and no anonymous frame is set. Use -h for help." - ); + + const char* sFrame = DasVar_getFrameName(pCalc->pVarIn); + if(sFrame == NULL){ + if((sAnonFrame == NULL)||(sAnonFrame[0] == '\0')){ + return das_error(PERR, + "Can not add rotation operation, input vector has no frame " + "and no anonymous frame is set. Use -h for help." + ); + } + else{ + sFrame = sAnonFrame; + } } - strncpy(pReq->aInFrame, sAnonFrame, DASFRM_NAME_SZ - 1); + strncpy(pReq->aInFrame, sFrame, DASFRM_NAME_SZ - 1); } /* The shape the storage array is just the same as the input, with all @@ -898,16 +906,21 @@ DasErrCode _addRotation(XCalc* pCalc, const char* sAnonFrame, DasDs* pDsOut) const DasDim* pDimIn = (const DasDim*)DasDesc_parent((const DasDesc*)(pCalc->pVarIn)); const char* sDimIn = DasDim_dim(pDimIn); + /* If the input array is a double, move up to doubles for the output */ + const DasAry* pAryIn = DasVar_getArray(pCalc->pVarIn); + das_val_type vtElOut = ((pAryIn != NULL)&&(DasAry_valType(pAryIn) == vtDouble)) ? + vtDouble : vtFloat; + snprintf(sId, 63, "%s_%s", sDimIn, pReq->aOutFrame); DasAry* pAryOut = new_DasAry( - sId, vtFloat, 0, NULL, nAryRank, aAryShape, DasVar_units(pCalc->pVarIn) + sId, vtDouble, 0, NULL, nAryRank, aAryShape, DasVar_units(pCalc->pVarIn) ); DasDs_addAry(pDsOut, pAryOut); /* Now add a codec for this array, assumes time is record varying */ if(nItems > 0){ DasDs_addFixedCodec( - pDsOut, DasAry_id(pAryOut), "real", g_sFloatEnc, das_vt_size(vtFloat), nItems, + pDsOut, DasAry_id(pAryOut), "real", g_sFloatEnc, das_vt_size(vtElOut), nItems, DASENC_WRITE ); } @@ -915,8 +928,8 @@ DasErrCode _addRotation(XCalc* pCalc, const char* sAnonFrame, DasDs* pDsOut) /* DAS_FLOAT_SEP : contains binary patterns almost never seen in floating point serialization. See codec.c */ DasDs_addRaggedCodec( - pDsOut, DasAry_id(pAryOut), "real", g_sFloatEnc, das_vt_size(vtFloat), - nAryRank, das_vt_size(vtFloat), &(DAS_FLOAT_SEP[0][0]), DASENC_WRITE + pDsOut, DasAry_id(pAryOut), "real", g_sFloatEnc, das_vt_size(vtElOut), + nAryRank, das_vt_size(vtElOut), &(DAS_FLOAT_SEP[0][0]), DASENC_WRITE ); }