diff --git a/das2/dataset_hdr3.c b/das2/dataset_hdr3.c index 79065aa..5a6533f 100644 --- a/das2/dataset_hdr3.c +++ b/das2/dataset_hdr3.c @@ -697,17 +697,22 @@ static DasErrCode _serial_makeVarAry(context_t* pCtx, bool bHandleFill) if(pCtx->aVarMap[i] == DASIDX_UNUSED) continue; - if(pCtx->aExtShape[pCtx->aVarMap[i]] == DASIDX_RAGGED){ - aShape[nAryRank] = 0; + /* if(pCtx->aExtShape[pCtx->aVarMap[i]] == DASIDX_RAGGED){ */ + + if(pCtx->aExtShape[i] == DASIDX_RAGGED){ + aShape[ pCtx->aVarMap[i] ] = 0; } else{ - if(pCtx->aExtShape[pCtx->aVarMap[i]] <= 0){ + /* if(pCtx->aExtShape[pCtx->aVarMap[i]] <= 0){ */ + + if(pCtx->aExtShape[i] <= 0){ return das_error(DASERR_SERIAL, "Invalid array map for variable %s:%s in dataset id %d", DasDim_id(pCtx->pCurDim), pCtx->varUse, pCtx->nPktId ); } - aShape[nAryRank] = pCtx->aExtShape[pCtx->aVarMap[i]]; + /* aShape[nAryRank] = pCtx->aExtShape[pCtx->aVarMap[i]]; */ + aShape[ pCtx->aVarMap[i] ] = pCtx->aExtShape[i]; } ++nAryRank; diff --git a/das2/var_ary.c b/das2/var_ary.c index 763be17..5edf5ea 100644 --- a/das2/var_ary.c +++ b/das2/var_ary.c @@ -410,6 +410,7 @@ bool _DasVarAry_canStride( return (iFirstRagged == -1) || (nSzFirstUsed == 1); } +/* This is a handler for both DasVarAry and DasVarVecAry */ /* NOTES in: variable.md. */ DasAry* _DasVarAry_strideSubset( const DasVarAry* pThis, const ptrdiff_t* pMin, const ptrdiff_t* pMax, @@ -422,6 +423,11 @@ DasAry* _DasVarAry_strideSubset( int nVarRank = pThis->base.nExtRank; size_t elSz = pThis->base.vsize; + das_val_type vtEl = pThis->base.vt; + if(pThis->base.vt == vtGeoVec){ + vtEl = ((DasVarVecAry*)pThis)->tplt.et; + } + /* Allocate the output array and get a pointer to the memory */ size_t aSliceShape[DASIDX_MAX] = DASIDX_INIT_BEGIN; @@ -430,12 +436,12 @@ DasAry* _DasVarAry_strideSubset( char sName[DAS_MAX_ID_BUFSZ] = {'\0'}; snprintf(sName, DAS_MAX_ID_BUFSZ - 1, "%s_subset", DasAry_id(pThis->pAry)); DasAry* pSlice = new_DasAry( - sName, pThis->base.vt, pThis->base.vsize, DasAry_getFill(pThis->pAry), + sName, vtEl, pThis->base.vsize, DasAry_getFill(pThis->pAry), nSliceRank, aSliceShape, pThis->base.units ); size_t uWriteBufLen = 0; - ubyte* pWriteBuf = DasAry_getBuf(pSlice, pThis->base.vt, DIM0, &uWriteBufLen); + ubyte* pWriteBuf = DasAry_getBuf(pSlice, vtEl, DIM0, &uWriteBufLen); /* Get the base starting point pointer */ ptrdiff_t base_idx[DASIDX_MAX] = {0}; @@ -448,7 +454,7 @@ DasAry* _DasVarAry_strideSubset( } size_t uRemain = 0; const ubyte* pBaseRead = DasAry_getIn( - pThis->pAry, pThis->base.vt, DasAry_rank(pThis->pAry), base_idx, &uRemain + pThis->pAry, vtEl, DasAry_rank(pThis->pAry), base_idx, &uRemain ); if(pBaseRead == NULL){ *pContinue = false; @@ -490,7 +496,7 @@ DasAry* _DasVarAry_strideSubset( ubyte* pWrite = pWriteBuf; /* Copy the data. Unroll the loop up to dimension 4. Unchecked there - * are *all* kinds of security errors here: + * are *all* kinds of security concerns here: * * 1. We could write off the end of the buffer * 2. We could read outside array memory. @@ -623,14 +629,24 @@ DasAry* _DasVarAry_directSubset( } } - /* Look over the array range and make sure it points to a single subset */ ptrdiff_t aAryShape[DASIDX_MAX]; int nAryRank = DasAry_shape(pThis->pAry, aAryShape); + + /* If we have internal indicies, use the full range for them */ + /* if( ((DasVar*)pThis)->nIntRank > 0){ + assert( ((DasVar*)pThis)->nIntRank == 1); / * No high internal ranks yet * / + assert( aAryShape[nAryRank - 1] > 0); / * No var-len internal yet * / + + aAryMin[ aAryShape[nAryRank - 1] ] = 0; + aAryMax[ aAryShape[nAryRank - 1] ] = aAryShape[nAryRank - 1]; + } + */ + + /* Look over the array range and make sure it points to a single subset */ ptrdiff_t aLoc[DASIDX_MAX]; int nLocSz = 0; int iBegFullRng = -1; - - for(iDim = 0; iDim < nAryRank; ++iDim){ + for(iDim = 0; iDim < (nAryRank - ((DasVar*)pThis)->nIntRank); ++iDim){ /* Sanity check */ if((aAryMin[iDim] < 0)||(aAryMax[iDim] > aAryShape[iDim])){ diff --git a/utilities/das3_cdf.c b/utilities/das3_cdf.c index 3a06432..b945bdd 100644 --- a/utilities/das3_cdf.c +++ b/utilities/das3_cdf.c @@ -1673,7 +1673,9 @@ const char* DasVar_cdfUniqName( /* Sequences pour themselves into the shape of the containing dataset - so the dataset shape is needed here */ + so the dataset shape is needed here. Vectors with just a single + component have the internal index dropped +*/ long DasVar_cdfNonRecDims( int nDsRank, ptrdiff_t* pDsShape, const DasVar* pVar, long* pNonRecDims ){ @@ -1707,8 +1709,10 @@ long DasVar_cdfNonRecDims( ptrdiff_t aIntr[DASIDX_MAX] = {0}; int nIntrRank = DasVar_intrShape(pVar, aIntr); for(int i = 0; i < nIntrRank; ++i){ - pNonRecDims[nUsed] = aIntr[i]; - ++nUsed; + if(aIntr[i] > 1){ + pNonRecDims[nUsed] = aIntr[i]; + ++nUsed; + } } } @@ -1829,12 +1833,13 @@ DasErrCode makeCdfVar( } else aMax[r] = 1; - } + } /* Force all sequences and binary variables to take on concrete values */ DasAry* pAry = DasVar_subset(pVar, nDsRank, aMin, aMax); ptrdiff_t aAryShape[DASIDX_MAX] = DASIDX_INIT_UNUSED; + ptrdiff_t aTmp[DASIDX_MAX] = DASIDX_INIT_UNUSED; int nAryRank = DasAry_shape(pAry, aAryShape); size_t uLen = 0; @@ -1846,8 +1851,12 @@ DasErrCode makeCdfVar( long counts[DASIDX_MAX] = {0,0,0,0, 0,0,0,0}; static const long intervals[DASIDX_MAX] = {1,1,1,1, 1,1,1,1}; - for(int r = 0; r < nAryRank; ++r){ - counts[r] = aAryShape[r]; + /* shave off any length 1 indexes after the first when saving to CDF */ + int iDimOut = 0; + for(int iDimIn = 0; iDimIn < nAryRank; ++iDimIn){ + if((iDimIn > 0) && (aAryShape[iDimIn] == 1)) continue; + counts[iDimOut] = aAryShape[iDimIn]; + ++iDimOut; } iStatus = CDFhyperPutzVarData( @@ -1893,6 +1902,12 @@ DasErrCode makeCompLabels(struct context* pCtx, DasDim* pDim, DasVar* pVar) if(nLen > nMaxCompLen) nMaxCompLen = nLen; } + /* If there's only one component, short cut this branch and just make a + regular label */ + if(nComp == 1){ + return writeVarStrAttr(pCtx, DasVar_cdfId(pVar), "LABEL", psBuf[0]); + } + /* Get the primary variable's name */ char sVarName[CDF_VAR_NAME_LEN256] = {'\0'}; if(CDF_MAD(CDFgetzVarName(pCtx->nCdfId, DasVar_cdfId(pVar), sVarName))) @@ -1941,8 +1956,17 @@ DasErrCode makeCompLabels(struct context* pCtx, DasDim* pDim, DasVar* pVar) nRet = writeVarStrAttr(pCtx, nLblVarId, "CATDESC", sBuf); - /* And finally, set the lable pointer for the main variable */ - return writeVarStrAttr(pCtx, DasVar_cdfId(pVar), "LABL_PTR_1", sLblVarName); + /* And finally, set the lable pointer for the main variable, the index it's a label + for is always the last one. */ + int iLblIdx = 1; + const DasAry* pAry = DasVar_getArray(pVar); + if(pAry == NULL) + return das_error(PERR, "Vector variable in %s is not backed by an array", DasDim_id(pDim)); + + iLblIdx = DasAry_rank(pAry) - 1; + memset(sBuf, 0, 256); + snprintf(sBuf, 32, "LABL_PTR_%d", iLblIdx); + return writeVarStrAttr(pCtx, DasVar_cdfId(pVar), sBuf, sLblVarName); } /* ************************************************************************ */ @@ -1973,6 +1997,12 @@ DasErrCode writeVarProps( DasVar_shape(pVar, aVarShape); int iIdxMax = _maxIndex(aVarShape); + /* There could be holes in the indexes used by the dataset, so + collapse the deps numbers */ + int iDep = -1; + for(int i = 0; i <= iIdxMax; ++i) + if((aVarShape[i] > -1)&&(i != iAmDep)) ++iDep; + for(int iIdx = iIdxMax; iIdx >= 0; --iIdx){ /* Either not record varying, or not affected by this index */ @@ -1985,7 +2015,8 @@ DasErrCode writeVarProps( /* Find the dependency for my current index */ for(size_t u = 0; u < uCoords; ++u){ if((pCoords + u)->iDep == iIdx){ - snprintf(sAttrName, 15, "DEPEND_%d", iIdx); + snprintf(sAttrName, 15, "DEPEND_%d", iDep); + --iDep; writeVarStrAttr( pCtx, DasVar_cdfId(pVar), diff --git a/utilities/das3_spice.c b/utilities/das3_spice.c index 90eea0c..7eb6287 100644 --- a/utilities/das3_spice.c +++ b/utilities/das3_spice.c @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef _WIN32 #define strcasecmp _stricmp #define strncasecmp _strnicmp @@ -933,7 +934,11 @@ DasErrCode _addRotation(XCalc* pCalc, const char* sAnonFrame, DasDs* pDsOut) vtDouble : vtFloat; char sId[64] = {'\0'}; - snprintf(sId, 63, "%s_%s", sIdIn, pReq->aOutFrame); + char sOutFrmLo[32] = {'\0'}; + int nLen = strlen(pReq->aOutFrame); + nLen = nLen < 32 ? nLen : 31; + for(int i = 0; i < nLen; ++i) sOutFrmLo[i] = tolower(pReq->aOutFrame[i]); + snprintf(sId, 63, "%s_%s", sIdIn, sOutFrmLo); DasAry* pAryOut = new_DasAry( sId, vtDouble, 0, NULL, nAryRank, aAryShape, DasVar_units(pCalc->pVarIn) ); @@ -971,8 +976,8 @@ DasErrCode _addRotation(XCalc* pCalc, const char* sAnonFrame, DasDs* pDsOut) pCalc->pVarOut = pVarOut; /* attach the output location */ - /* We will have the same basic property as upstream */ - + /* We will have the same basic properties as upstream, except for the + cdfName if found */ DasDim* pDimOut = new_DasDim(sDimIn, sId, DasDim_type(pDimIn), nDsRank); DasDim_setFrame(pDimOut, pReq->aOutFrame); DasDim_addVar(pDimOut, DASVAR_CENTER, pVarOut); @@ -980,8 +985,20 @@ DasErrCode _addRotation(XCalc* pCalc, const char* sAnonFrame, DasDs* pDsOut) /* Copy over the properties, and change a few */ DasDesc_copyIn((DasDesc*)pDimOut, (const DasDesc*)pDimIn); DasDesc_setStr((DasDesc*)pDimOut, "frame", pReq->aOutFrame); + + /* update the cdfName property if that's found */ char sBuf[128] = {'\0'}; - snprintf(sBuf, 127, "%s values rotated into %s", DasDim_id(pDimIn), pReq->aOutFrame); + if(DasDesc_has((DasDesc*)pDimOut, "cdfName")){ + snprintf(sBuf, 64, "%s_%s", DasDesc_getStr((DasDesc*)pDimOut, "cdfName"), sOutFrmLo); + DasDesc_setStr((DasDesc*)pDimOut, "cdfName", sBuf); + memset(sBuf, 0, 128); + snprintf(sBuf, 127, "%s values rotated into %s", + DasDesc_getStr((DasDesc*)pDimIn, "cdfName"), pReq->aOutFrame + ); + } + else{ + snprintf(sBuf, 127, "%s values rotated into %s", DasDim_id(pDimIn), pReq->aOutFrame); + } DasDesc_setStr((DasDesc*)pDimOut, "summary", sBuf); /* toss a bone to the cdf writer if it happens to be downstream */