libdas2
das2 core C utilities
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
dimension.h
1 /* Copyright (C) 2018 Chris Piker <chris-piker@uiowa.edu>
2  *
3  * This file is part of libdas2, the Core Das2 C Library.
4  *
5  * Libdas2 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  * Libdas2 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 libdas2; if not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef _das_dimension_h_
19 #define _das_dimension_h_
20 
21 #include <das2/descriptor.h>
22 #include <das2/variable.h>
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 #define DASDIM_MAXDEP 16 // Arbitrary decision, can be changed
29 #define DASDIM_MAXVAR 16 // Another arbitrary changable descision
30 
31 
32 /* OFFSET and REFERENCE variable roles were a tough call. In the end you only
33  * need center values to do DFT's. The DFT code should look at the coordinate
34  * series and see what if it has a constant change in index. If so, you can do
35  * a DFT, otherwise you can't.
36  *
37  * Currently in das 2.2 land we know that one "package" of values is a
38  * continuous waveform set. We can look at the yTags, see if they are
39  * consistent and the if they are then we can transform. It's very clear when
40  * we can do this, but it's also it requires a very specific data structure.
41  * So in a general data model, how do you get the yTags? You *can* do it with a
42  * morphology check but those tend to be a rabbit hole of exploding if
43  * statements.
44  *
45  * The initial thought was to have offset dimensions, but that caused a massive
46  * symmetry break in the data model. Why have a rule that always combines two
47  * dimensions with a + operator? Why not other operators? Also, if you set
48  * say the the "STD_DEV" variable in the reference dimension and also in the
49  * offset dimension, how do you combine those? It seems offset dimensions
50  * trigger more problems then they solve.
51  *
52  * The solution taken here is to introduce two variable roles, REFERENCE and
53  * OFFSET. Since this choice only requires adding two string constants it can
54  * be ignored if turns out it's a bad choice. Otherwise it simplifies the
55  * concept of breaking down values into a reference point that may change for
56  * each packet and a set of fixed offsets. These sorts of coordinates come up
57  * a lot in our work, for example frequency values for down-mixed data, radar
58  * return altitudes and waveform captures.
59  *
60  * DASVAR_CENTER should still be provided for client codes that don't understand
61  * the offset and reference semantic. And since this can be done with one
62  * call to new_DasVarBinary() without exploding the network data volume
63  * it doesn't seem like that much of a burden.
64  *
65  * Another approach would have been to expand properties to include an
66  * index/value relationship section. We could define things like constant
67  * change of value for a change in a certain index and then define if rolling
68  * the next index up is the same change as the lower index roll. This seemed
69  * like a much more complicated idea and didn't work so well with offsets that
70  * are constant by record (i.e. the i value) but not constant by value index
71  * (j,k,l ...).
72  * -cwp
73  */
74 
75 #ifndef _das_dimension_c_
76 extern const char* DASVAR_CENTER;
77 extern const char* DASVAR_MIN;
78 extern const char* DASVAR_MAX;
79 extern const char* DASVAR_WIDTH;
80 extern const char* DASVAR_MEAN; /* all these can substitute for the center */
81 extern const char* DASVAR_MEDIAN; /* if the center is missing but they are */
82 extern const char* DASVAR_MODE; /* distinct so it's good to include them here */
83 extern const char* DASVAR_REF;
84 extern const char* DASVAR_OFFSET;
85 extern const char* DASVAR_MAXERR;
86 extern const char* DASVAR_MINERR;
87 extern const char* DASVAR_UNCERT;
88 extern const char* DASVAR_STD_DEV;
89 extern const char* DASVAR_SPREAD;
90 extern const char* DASVAR_WEIGHT;
91 #endif
92 
98 enum dim_type { DASDIM_UNK = 0, DASDIM_COORD, DASDIM_DATA };
99 
121 typedef struct das_dim {
122  DasDesc base; /* Attributes or properties for this variable */
123  enum dim_type dtype; /* Coordinate or Data flag */
124  char sId[64]; /* A name for this dimension */
125 
126  /* Holds the max index to report out of this dimension.
127  * The dimension may have internal indices beyond these
128  * but they are not correlated with the overall dataset
129  * indicies */
130  int iFirstInternal;
131 
132  /* The variables which supply data for this dimension */
133  DasVar* aVars[DASDIM_MAXVAR];
134  char aRoles[DASDIM_MAXVAR][32];
135  size_t uVars;
136 
137  /* For dependent variables (i.e. data) pointers to relavent independent
138  * dimensions are here. I don't think we need this here as the dataset
139  * provides this information. Going to punt it for now but will use
140  * DasVar_orthoginalTo() when printing coordinate information */
141  /* struct das_dim* aCoords[DASDIM_MAXDEP];
142  size_t uCoords;*/
143 } DasDim;
144 
145 
160 DasDim* new_DasDim(const char* sId, enum dim_type dtype, int nRank);
161 
170 const char* DasDim_id(const DasDim* pThis);
171 
172 
183 char* DasDim_toStr(const DasDim* pThis, char* sBuf, int nLen);
184 
200 int DasDim_copyInProps(DasDim* pThis, char cAxis, const DasDesc* pOther);
201 
202 
221 bool DasDim_addVar(DasDim* pThis, const char* sRole, DasVar* pVar);
222 
223 
238 const DasVar* DasDim_getVar(const DasDim* pThis, const char* sRole);
239 
258 const DasVar* DasDim_getPointVar(const DasDim* pThis);
259 
260 
279 DasVar* DasDim_popVar(DasDim* pThis, const char* role);
280 
287 void del_DasDim(DasDim* pThis);
288 
289 
331 int DasDim_shape(const DasDim* pThis, ptrdiff_t* pShape);
332 
333 
350 ptrdiff_t DasDim_lengthIn(const DasDim* pThis, int nIdx, ptrdiff_t* pLoc);
351 
352 
355 #ifdef __cplusplus
356 }
357 #endif
358 
359 #endif /* _das_dimension_h_ */
360 
Das2 Physical Dimensions.
Definition: dimension.h:121
char * DasDim_toStr(const DasDim *pThis, char *sBuf, int nLen)
Print an information string describing a dimension.
Das2 fexible variables.
Definition: variable.h:207
void del_DasDim(DasDim *pThis)
Delete a dimension and drop the reference count on all contained variables.
const char * DasDim_id(const DasDim *pThis)
Get the dimension&#39;s id.
ptrdiff_t DasDim_lengthIn(const DasDim *pThis, int nIdx, ptrdiff_t *pLoc)
Return the current max value index value + 1 for any partial index.
DasDim * new_DasDim(const char *sId, enum dim_type dtype, int nRank)
Create a new dimension (not as impressive as it sounds)
Base structure for Stream Header Items.
Definition: descriptor.h:80
DasVar * DasDim_popVar(DasDim *pThis, const char *role)
Remove a variable by role from a dimensions.
bool DasDim_addVar(DasDim *pThis, const char *sRole, DasVar *pVar)
Add a variable to a dimension.
int DasDim_copyInProps(DasDim *pThis, char cAxis, const DasDesc *pOther)
Copy in dataset properties from some other descriptor.
const DasVar * DasDim_getPointVar(const DasDim *pThis)
Get a variable poviding single point values in a dimension.
correlated data and coordinate variables
int DasDim_shape(const DasDim *pThis, ptrdiff_t *pShape)
Get the maximum extent of this dimension in index space.
const DasVar * DasDim_getVar(const DasDim *pThis, const char *sRole)
Get a variable providing values for a particular role in the dimension.