das2C
das core C utilities (v3)
Loading...
Searching...
No Matches
dataset.h
Go to the documentation of this file.
1/* Copyright (C) 2017-2024 Chris Piker <chris-piker@uiowa.edu>
2 *
3 * This file is part of das2C, the Core Das2 C Library.
4 *
5 * das2C is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Lesser General Public License version 2.1 as published
7 * by the Free Software Foundation.
8 *
9 * das2C is distributed in the hope that it will be useful, but WITHOUT ANY
10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * version 2.1 along with das2C; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18
21#ifndef _das_dataset_h_
22#define _das_dataset_h_
23
24#include <das3/dimension.h>
25#include <das3/codec.h>
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/* Old initial comment that kicked off the entire das2 data model design...
32 *
33 * The structures below are the start of an idea on how to get independent
34 * parameters for data at any particular index. These are just thoughts
35 * at the moment and don't affect any working code. There are many ways
36 * to do this. The CDF and QStream assumption is that there are the same
37 * number of parameters locating a data point in parameter space as there
38 * are indices to the dataset. Because of this x,y,z scatter data are
39 * hard to handle.
40 *
41 * For x,y,z scatter lists there is 1 index for any point in the dataset,
42 * but for each index there are 2 independent parameters. Basically QStream
43 * and CDF assume that all datasets are CUBEs in parameter space but this
44 * is not the case for a great many sets.
45 *
46 * To adequately handle these 'path' datasets a parameter map is required.
47 * The mapping takes 1 index value per data rank and returns 1 to N parameter
48 * values.
49 *
50 * These structures start to handle this idea but are just doodles at this
51 * point. -cwp 2017-07-25
52 */
53
54/* Second comment that added desire for flexible data types ...
55 *
56 * Thinking about coordinate returns, how about a data set of thefts / month
57 * in 5 cities... Won't usually come up, but should be possible
58 * to handle. Here's the data set:
59 *
60 * 2016-01 2016-02 2016-03 2016-04 2016-05 2016-06
61 * Baltimore 2351 3789 4625 5525 6135 5902
62 * Bogotaƃ 109065 110365 99625 98265 43850 33892
63 * Chicago 4789 5764 8901 10145 13456 22678
64 * Des Moines 4 10 33 35 44 107
65 *
66 * Properties: Title -> "Thefts/Month for selected cities"
67 *
68 * Okay, the X axis data type is text[12] (need null char)
69 * Y axis data type is datetime
70 * Z axis data type is datum, "thefts month**-1"
71 *
72 * So what is the return value from pDs->bin(pDs, 0, 0) ?
73 *
74 * The bin is defined on the space of all UTC times, and on the space of all
75 * cities in the data set.
76 *
77 *
78 * So, what about this common data set, interference events:
79 *
80 * |<---------- Bin ------>| |<----- Value --->|
81 * 2016-01-01T14:00 2016-01-02T02:20 Mag Roll
82 * 2016-01-01T15:40 2016-01-01T15:41 Stabilization Pulse
83 * 2016-01-01T15:43 2016-01-01T15:44 Stabilization Pulse
84 * 2016-01-01T15:45 2016-01-01T15:47 Stabilization Pulse
85 * 2016-01-01T15:48 2016-01-01T15:50 Stabilization Pulse
86 *
87 * So what is the return value from pDs->bin(pDs, 0) ?
88 *
89 * The space is UTC time, So each bin start and stop is defined on the space
90 * of all UTC times.
91 * -cwp 2017-??-??
92 */
93
94/* Number of encoders that can be stored internally, more then this and they
95 * have to be allocated on the heap.
96 *
97 * Current test case with the most codec/dateste is ex21, at 7.
98 * If you bump this make a test case with one more variable than the new
99 * value below.
100 */
101#define DASDS_LOC_ENC_SZ 6
102
103/* Small vector size for array and dimension pointer sets. Larger then
104 * DASDS_LOC_ENC_SZ because these are just sizeof(void*) each not ~200 B.
105 *
106 * NOTE: No test case reaches these sizes, but both were reduced to 6 for
107 * a onetime test against ex21_tracers_cdpu_status.d3b (uDims=7,
108 * uArrays=7), on 2026-07-16.
109 *
110 * If you touch the dynamic #of array or dims code, drop these back to 6
111 * each and run `make test`.
112 */
113#define DASDS_LOC_ARY_SZ 32
114#define DASDS_LOC_DIM_SZ 32
115
116/* Room for the longest PlotType, "cartesian3d:movie", update if schema changes. */
117#define DASDS_PLOT_SZ 24
118
159typedef struct dataset {
160 DasDesc base; /* This would be equivalent to the properties for
161 a packet descriptor. Typically in das 2.2 packets
162 don't have a descriptor, only streams and planes
163 but access to the stream descriptor forwards through
164 here. */
165
166 int nRank; /* The number of whole-dataset index dimensions.
167 * Variables can define internal dimensions but they
168 * can't use indices in the first nRank positions for
169 * internal use, as these are used to correlate values
170 * across the dataset. */
171
172 /* The dataset's name, unique within its group; (sGroupId, sId) is the
173 * dataset key. Written as name= in das3 headers. */
174 char sId[DAS_MAX_ID_BUFSZ];
175
176 /* The join group for this dataset. Datasets with the same group should
177 * be joined automatically by display clients. Empty is the null group,
178 * which joins nothing. Written as group= in das3 headers, and is what
179 * das2 calls a plane or packet name. */
180 char sGroupId[DAS_MAX_ID_BUFSZ];
181
182 /* Overall plotting hint for dataset consumers, same idea as DasDim.axis.
183 See schema for legal values */
184 char sPlot[DASDS_PLOT_SZ];
185
186 size_t uDims; /* Number of dimensions, das datasets are
187 * implicitly bundles in qdataset terms. */
188
189 DasDim** lDims; /* The data variable object arrays, internal or external */
190 size_t uSzDims; /* lDims memory size, internal or external */
191
192 DasDim* aDims[DASDS_LOC_DIM_SZ]; /* small vector memory */
193
194 size_t uArrays; /* The number of low-level arrays */
195 DasAry** lArrays; /* Array objects, internal or external */
196 size_t uSzArrays; /* lArrays memory size, internal or external */
197
198 DasAry* aArrays[DASDS_LOC_ARY_SZ]; /* small vector memory */
199
200 ptrdiff_t _shape[VARIDX_MAX]; /* cache shape calls for speed */
201
202 bool _dynamic; /* If true, the dataset may still be changing and all
203 bulk properties such as the iteration shape should be
204 recalculated instead of using cached values.
205 If false, cached values are expected to already be
206 available */
207
208 /* dataset arrays can be written in chunks to output buffers. The number of
209 * elements in each chuck, the encoding of each element any separators are
210 * defined below. */
211 /* DasCodec** lEncs; */
212
213 size_t uCodecs; /* Number of valid codecs */
214
215 /* These become large vector memory when uSzEncs > DASDS_LOC_ENC_SZ */
216
217 /* When the number of valid codecs grows past DASDS_LOC_ENC_SZ, use an
218 external buffer for all of them */
219
220 DasCodec* lCodecs; /* Codec pointers, internal or external */
221 int* lItems; /* Number of items to decode per codec, internal or ex */
222 size_t uSzCodecs; /* Codec & Item array memory size, internal or external */
223
224 DasCodec aCodecs[DASDS_LOC_ENC_SZ]; /* small vector memory */
225 int aItems[DASDS_LOC_ENC_SZ]; /* small vector memory */
226
227 /* Set to true when encode is called, make sure data doesn't go
228 * out the door unless the descriptor is sent first */
229 bool bSentHdr;
230
238 void* pUser;
239
240} DasDs;
241
282 const char* sId, const char* sGroupId, int nRank
283);
284
317DAS_API DasDs* DasDs_copy(const DasDs* pThis);
318
351DAS_API DasErrCode DasDs_replaceAry(DasDs* pThis, const char* sOldId, DasAry* pNew);
352
362DAS_API void del_DasDs(DasDs* pThis);
363
380DAS_API void DasDs_setMutable(DasDs* pThis, bool bChangeAllowed);
381
382
387#define DasDs_mutable(P) P->_mutable
388
432DAS_API int DasDs_shape(const DasDs* pThis, ptrdiff_t* pShape);
433
451DAS_API ptrdiff_t DasDs_lengthIn(const DasDs* pThis, int nIdx, ptrdiff_t* pLoc);
452
453
470#define DasDs_group(P) ((const char*)(P)->sGroupId)
471
482#define DasDs_id(P) ((const char*)(P)->sId)
483
496#define DasDs_getPlot(P) ((const char*)(P)->sPlot)
497
507DAS_API DasErrCode DasDs_setPlot(DasDs* pThis, const char* sPlot);
508
509
526#define DasDs_rank(P) ((P)->nRank)
527
550DAS_API DasErrCode DasDs_addAry(DasDs* pThis, DasAry* pAry);
551
552
557#define DasDs_numAry(P) ((P)->uArrays)
558
566#define DasDs_getAry(P, I) ((P)->lArrays[(I)])
567
568
583DAS_API DasAry* DasDs_getAryById(DasDs* pThis, const char* sAryId);
584
606DAS_API size_t DasDs_memUsed(const DasDs* pThis);
607
612DAS_API size_t DasDs_memIndexed(const DasDs* pThis);
613
633DAS_API size_t DasDs_memOwned(const DasDs* pThis);
634
641#define DasDs_numCodecs( pThis ) ( (pThis)->uCodecs )
642
650#define DasDs_getCodec( pThis, I ) ( &( (pThis)->lCodecs[(I)] ) )
651
668 const DasDs* pThis, const char* sAryId, int* pItems
669);
670
676#define DasDs_pktItems( P, I ) ( (P)->lItems[(I)] )
677
723 DasDs* pThis, const char* sAryId, const char* sSemantic,
724 const char* sEncType, int nItemBytes, int nNumItems, bool bRead
725);
726
771 DasDs* pThis, const char* sAryId, const char* sSemantic,
772 const char* sEncType, int nItemTerm, ubyte uTerm, int nNumItems,
773 bool bRead
774);
775
776
802 DasDs* pThis, const char* sAryId, const DasCodec* pOther, int nNumItems,
803 bool bRead
804);
805
824DAS_API DasDs* new_DasDs_xml(DasBuf* pBuf, DasDesc* pParent, int nPktId);
825
842DAS_API DasErrCode DasDs_encodeHdr(DasDs* pThis, DasBuf* pBuf);
843
859
876DAS_API DasErrCode DasDs_encodeData(DasDs* pThis, DasBuf* pBuf, ptrdiff_t iIdx0);
877
878
894DAS_API int DasDs_recBytes(const DasDs* pThis);
895
896
915DAS_API size_t DasDs_clearRagged0(DasDs* pThis);
916
917
941 DasDs* pThis, enum dim_type dType, const char* sDim, const char* sId
942);
943
958DAS_API DasErrCode DasDs_addDim(DasDs* pThis, DasDim* pDim);
959
967DAS_API size_t DasDs_numDims(const DasDs* pThis, enum dim_type dmt);
968
969
978 DasDs* pThis, const char* sDim, enum dim_type dmt
979);
980
989 DasDs* pThis, size_t idx, enum dim_type vt
990);
991
1003DAS_API DasDim* DasDs_getDimById(DasDs* pThis, const char* sId);
1004
1005
1033DAS_API int DasDs_info(const DasDs* pThis, char* sBuf, size_t uLen);
1034
1051DAS_API char* DasDs_toStr(const DasDs* pThis, char* sBuf, size_t uLen);
1052
1053
1073DAS_API bool DasDs_cubicCoords(const DasDs* pThis, const DasDim** pCoords);
1074
1075
1076
1077
1078/* Ideas I'm still working on...
1079
1080bool DataGen_grid(const DataSet* pDataset);
1081
1082const DataSet** Dg_griddedIn(const DataSet* pDataset);
1083
1084
1085/ * The two functions below are really useful but I'll need to crack open
1086 a double pack of Flex and Bison to get it done so I'm punting for now. * /
1087
1088/ * Ex Expression: $spec_dens[i][j][k] * /
1089const Function* Dataset_evalDataExp(Dataset* pThis, const char* sExpression);
1090
1091/ * Ex Expression: $craft_alt[i][j] - 0.5 * $delay_time[k] * 299792 * /
1092const Function* Dataset_evalCoordExp(Dataset* pThis, const char* sExpression);
1093
1094
1095/ ** Get the coefficients for iterating over a 1-D slice of a regular (i.e.
1096 * non-ragged) dataset.
1097 *
1098 * This function dose not work for ragged datasets and merely returns NULL if
1099 * asked for iteration coefficients for such a set. In such a case use
1100 * Dataset_copySlice1D().
1101 *
1102 * /
1103const void* Dataset_slice1D(
1104 const Dataset* pThis, const char* sDs, const char* sCoord, int iCoordIdx,
1105 int* pCoeff
1106);
1107
1108/ ** Increment the reference count on any array objects that are part of
1109 * a data space.
1110 *
1111 * This is useful in instances where the underlying data arrays are going
1112 * to be represented by an organizational structure other than datasets
1113 * and DataSets since Das array objects only free data memory if their
1114 * reference count is zero.
1115 *
1116 * @param pThis
1117 * /
1118void DataSpace_incAryRef(Dataset* pThis);
1119
1120/ * Need a way to trigger callbacks from datasets changing, not just
1121 packets changing. It could be useful to work on items from the
1122 dataset level instead of just the packet level * /
1123 bool DataSpace_stream(Dataset* pThis); * /
1124
1125
1126
1127/ ** Indicate the physical degrees of freedom for a dataset by denoting a
1128 * complete list of coordinate sets.
1129 *
1130 * A list of coordinates over which an entire dataset is defined is called
1131 * a span. Datasets may have 1-N spans.
1132 * /
1133int DataSpace_addSpan(const char* sDsId, const char** lCoords, size_t nCoords);
1134*/
1135
1136#ifdef __cplusplus
1137}
1138#endif
1139
1140#endif /* _das_dataset_h */
Encoding/Decoding arrays to and from buffers.
DAS_API bool DasDs_cubicCoords(const DasDs *pThis, const DasDim **pCoords)
Get coordinate dimensions that satisfy the cubic dataset condition.
DAS_API DasDs * DasDs_copy(const DasDs *pThis)
Copy a dataset object.
DAS_API size_t DasDs_memIndexed(const DasDs *pThis)
The apparent memory usage of all arrays in the dataset.
#define VARIDX_MAX
Max index count for the model.
Definition generator.h:55
int DasErrCode
return code type 0 indicates success, negative integer indicates failure
Definition defs.h:189
Dynamic recursive ragged arrays.
Definition array.h:243
DAS_API size_t DasDs_clearRagged0(DasDs *pThis)
Clear any arrays that are ragged in index 0.
Buffer class to handle accumulating byte streams.
Definition buffer.h:47
Reading and writing array data to buffers.
Definition codec.h:45
Base structure for Stream Header Items.
Definition descriptor.h:74
Das Physical Dimensions.
Definition dimension.h:131
Das Datasets.
Definition dataset.h:159
DAS_API DasErrCode DasDs_encodeHdr(DasDs *pThis, DasBuf *pBuf)
Encode the dataset header as a das3 <dataset> XML element.
DAS_API size_t DasDs_numDims(const DasDs *pThis, enum dim_type dmt)
Get the number of physical dimensions in this dataset.
DAS_API DasErrCode DasDs_replaceAry(DasDs *pThis, const char *sOldId, DasAry *pNew)
Swap a storage array in a dataset for a replacement.
#define DasDs_addAry(D, A)
Add an array to the dataset, stealing it's reference.
DAS_API int DasDs_info(const DasDs *pThis, char *sBuf, size_t uLen)
Print a multi-line description of this dataset.
DAS_API DasCodec * DasDs_addStringCodec(DasDs *pThis, const char *sAryId, const char *sSemantic, const char *sEncType, int nItemTerm, ubyte uTerm, int nNumItems, bool bRead)
Define a packet data encoder for a fixed number of variable length items in each packet.
DAS_API DasCodec * DasDs_getCodecFor(const DasDs *pThis, const char *sAryId, int *pItems)
Get the codec for a named array.
DAS_API DasDs * new_DasDs(const char *sId, const char *sGroupId, int nRank)
Create a new dataset object.
DAS_API size_t DasDs_memUsed(const DasDs *pThis)
Get the currently used memory of all arrays in the dataset.
DAS_API void del_DasDs(DasDs *pThis)
Delete a Data object, cleaning up it's memory.
DAS_API size_t DasDs_memOwned(const DasDs *pThis)
Get the currently allocated memory of all arrays in the dataset.
DAS_API int DasDs_recBytes(const DasDs *pThis)
Get the number of bytes in each record of this dataset when serialized.
DAS_API void DasDs_setMutable(DasDs *pThis, bool bChangeAllowed)
Lock/Unlock the dataset for changes.
#define DasDs_makeDim(D, T, S)
Make a new dimension within this dataset.
DAS_API DasDim * DasDs_getDimById(DasDs *pThis, const char *sId)
Get a dimension by string id.
#define DasDs_getDim
Get a dimension by it's basic kind.
DAS_API DasCodec * DasDs_addFixedCodec(DasDs *pThis, const char *sAryId, const char *sSemantic, const char *sEncType, int nItemBytes, int nNumItems, bool bRead)
Define a packet data encoded/decoder for fixed length items and arrays.
DAS_API DasErrCode DasDs_decodeData(DasDs *pThis, DasBuf *pBuf)
Decode one packet's worth of data into dataset memory.
DAS_API DasErrCode DasDs_encodeData(DasDs *pThis, DasBuf *pBuf, ptrdiff_t iIdx0)
Encode one record's worth of data from dataset memory.
DAS_API int DasDs_shape(const DasDs *pThis, ptrdiff_t *pShape)
Return current valid ranges for whole data set iteration.
#define DasDs_toStr(P, B, N)
Print a one line summary of this dataset.
DAS_API DasDim * DasDs_getDimByIdx(DasDs *pThis, size_t idx, enum dim_type vt)
Get a dimension by index.
DAS_API DasDs * new_DasDs_xml(DasBuf *pBuf, DasDesc *pParent, int nPktId)
Parse a das3 <dataset> XML element into a new dataset object.
DAS_API DasAry * DasDs_getAryById(DasDs *pThis, const char *sAryId)
Get a dataset array given it's identifier.
DAS_API DasErrCode DasDs_addDim(DasDs *pThis, DasDim *pDim)
Add a physical dimension to the dataset.
DAS_API ptrdiff_t DasDs_lengthIn(const DasDs *pThis, int nIdx, ptrdiff_t *pLoc)
Return the current max value index value + 1 for any partial index.
DAS_API DasCodec * DasDs_addCodecFrom(DasDs *pThis, const char *sAryId, const DasCodec *pOther, int nNumItems, bool bRead)
Add a new codec that initialized via some other codec.
DAS_API DasErrCode DasDs_setPlot(DasDs *pThis, const char *sPlot)
Set the plot type hint for a dataset.
void * pUser
User data pointer.
Definition dataset.h:238
#define DAS_MAX_ID_BUFSZ
The size of an char buffer large enough to hold valid object IDs.
Definition util.h:348