1#include <lal/LALConfig.h>
3#ifndef LAL_HDF5_ENABLED
4int main(
void) {
return 77; }
7#if defined(GENERATE_HDF5_TEST_FILE)
16#include <lal/LALStdlib.h>
17#include <lal/AVFactories.h>
18#include <lal/StringVector.h>
21#include <lal/TimeSeries.h>
22#include <lal/FrequencySeries.h>
23#include <lal/H5FileIO.h>
25#define FNAME "test.h5"
26#define GROUP "path/to"
27#define DSET "testdset"
33#define NPTS (DIM0 * DIM1 * DIM2)
35#define EPOCH { 123456789, 987654321 }
41static int generate_int_data(
void)
43 return rand() % SHRT_MAX;
46static float generate_float_data(
void)
48 return rand() / (RAND_MAX + 1.0);
51static float complex generate_complex_data(
void)
53 return rand() / (RAND_MAX + 1.0) + I * rand() / (RAND_MAX + 1.0);
56static char * generate_string_data(
void)
59 switch (rand() % 18) {
60 case 0: s =
"lorem";
break;
61 case 1: s =
"ipsum";
break;
62 case 2: s =
"dolor";
break;
63 case 3: s =
"sit";
break;
64 case 4: s =
"amet";
break;
65 case 5: s =
"consectetur";
break;
66 case 6: s =
"adipiscing";
break;
67 case 7: s =
"elit";
break;
68 case 8: s =
"sed";
break;
69 case 9: s =
"eiusmod";
break;
70 case 10: s =
"tempor";
break;
71 case 11: s =
"incididunt";
break;
72 case 12: s =
"ut";
break;
73 case 13: s =
"labore";
break;
74 case 14: s =
"et";
break;
75 case 15: s =
"dolore";
break;
76 case 16: s =
"magna";
break;
77 case 17: s =
"aliqua";
break;
79 fprintf(stderr,
"Cannot get here!");
85#define DEFINE_WRITE_FUNCTION(type) \
86 static int write_ ## type (type *x) { \
89 XLALGPSTimeNow(&now); \
91 file = XLALH5FileOpen(FNAME, "w"); \
92 XLALH5FileAddLIGOTimeGPSAttribute(file, "creation_time_gps", &now); \
93 XLALH5FileAddScalarAttribute(file, "test_count", &count, LAL_U2_TYPE_CODE); \
94 group = XLALH5GroupOpen(file, GROUP); \
95 XLALH5FileAddStringAttribute(group, "test_data_type", #type); \
96 XLALH5FileWrite ## type (group, DSET, x); \
97 XLALH5FileClose(group); \
98 XLALH5FileClose(file); \
102#define DEFINE_READ_FUNCTION(type) \
103 static type * read_ ## type (void) { \
107 LIGOTimeGPS creation_time; \
109 char t[sizeof(#type)]; \
110 file = XLALH5FileOpen(FNAME, "r"); \
111 XLALH5FileQueryLIGOTimeGPSAttributeValue(&creation_time, file, "creation_time_gps"); \
112 if (XLALGPSCmp(&creation_time, &now)) { \
113 fprintf(stderr, " FAIL\n"); \
116 XLALH5FileQueryScalarAttributeValue(&cnt, file, "test_count"); \
117 if (cnt != count) { \
118 fprintf(stderr, " FAIL\n"); \
121 group = XLALH5GroupOpen(file, GROUP); \
122 XLALH5FileQueryStringAttributeValue(t, sizeof(t), group, "test_data_type"); \
123 XLALH5FileClose(group); \
124 if (strcmp(t, #type)) { \
125 fprintf(stderr, " FAIL\n"); \
128 x = XLALH5FileRead ## type (file, GROUP "/" DSET); \
129 XLALH5FileClose(file); \
133#define DEFINE_TEST_FUNCTION(type) \
134 static void test_ ## type (void) { \
137 fprintf(stderr, "Testing Read/Write of %s...", #type); \
138 orig = create_ ## type (); \
139 write_ ## type (orig); \
140 copy = read_ ## type (); \
141 if (compare_ ## type (orig, copy)) { \
142 fprintf(stderr, " FAIL\n"); \
145 XLALDestroy ## type (copy); \
146 XLALDestroy ## type (orig); \
147 fprintf(stderr, " PASS\n"); \
152#define DEFINE_CREATE_VECTOR_FUNCTION(type) \
153 static type * create_ ## type (void) { \
156 v = XLALCreate ## type (NPTS); \
157 for (i = 0; i < NPTS; ++i) \
158 v->data[i] = GENERATE_DATA(); \
162#define DEFINE_COMPARE_VECTOR_FUNCTION(type) \
163 static int compare_ ## type (type *v1, type *v2) { \
164 if (v1->length != v2->length) \
166 return memcmp(v1->data, v2->data, v1->length * sizeof(*v1->data)); \
174 for (i = 0; i < NPTS; ++i)
175 v->
data[i] = generate_string_data();
183 for (
size_t i = 0; i < v1->
length; ++i)
184 if (strcmp(v1->
data[i], v2->
data[i]) != 0)
191#define DEFINE_CREATE_ARRAY_FUNCTION(type) \
192 static type * create_ ## type (void) { \
195 a = XLALCreate ## type ## L(NDIM, DIM0, DIM1, DIM2); \
196 for (i = 0; i < NPTS; ++i) \
197 a->data[i] = GENERATE_DATA(); \
201#define DEFINE_COMPARE_ARRAY_FUNCTION(type) \
202 static int compare_ ## type (type *a1, type *a2) { \
203 size_t sz1 = 1, sz2 = 1, i; \
204 if (a1->dimLength->length != a2->dimLength->length) \
206 for (i = 0; i < a1->dimLength->length; ++i) { \
207 if (a1->dimLength->data[i] != a2->dimLength->data[i]) \
209 sz1 *= a1->dimLength->data[i]; \
210 sz2 *= a2->dimLength->data[i]; \
214 return memcmp(a1->data, a2->data, sz1 * sizeof(*a1->data)); \
219#define DEFINE_CREATE_TIME_FREQUENCY_SERIES_FUNCTION(type) \
220 static type * create_ ## type (void) { \
223 s = XLALCreate ## type ("test_" #type, &epoch, 0.0, 0.1, &lalStrainUnit, NPTS); \
224 for (i = 0; i < NPTS; ++i) \
225 s->data->data[i] = GENERATE_DATA(); \
229#define DEFINE_COMPARE_TIME_SERIES_FUNCTION(type) \
230 static int compare_ ## type (type *s1, type *s2) { \
232 if (s1->data->length != s2->data->length) \
234 if ((c = strcmp(s1->name, s2->name))) \
236 if ((c = (s1->deltaT > s2->deltaT) - (s1->deltaT < s2->deltaT))) \
238 if ((c = (s1->f0 > s2->f0) - (s1->f0 < s2->f0))) \
240 if (XLALUnitCompare(&s1->sampleUnits, &s2->sampleUnits)) \
242 return memcmp(s1->data->data, s2->data->data, s1->data->length * sizeof(*s1->data->data)); \
245#define DEFINE_COMPARE_FREQUENCY_SERIES_FUNCTION(type) \
246 static int compare_ ## type (type *s1, type *s2) { \
248 if (s1->data->length != s2->data->length) \
250 if ((c = strcmp(s1->name, s2->name))) \
252 if ((c = (s1->deltaF > s2->deltaF) - (s1->deltaF < s2->deltaF))) \
254 if ((c = (s1->f0 > s2->f0) - (s1->f0 < s2->f0))) \
256 if (XLALUnitCompare(&s1->sampleUnits, &s2->sampleUnits)) \
258 return memcmp(s1->data->data, s2->data->data, s1->data->length * sizeof(*s1->data->data)); \
261#define DEFINE_VECTOR_FUNCTIONS(type) \
262 DEFINE_WRITE_FUNCTION(type) \
263 DEFINE_READ_FUNCTION(type) \
264 DEFINE_COMPARE_VECTOR_FUNCTION(type) \
265 DEFINE_CREATE_VECTOR_FUNCTION(type) \
266 DEFINE_TEST_FUNCTION(type)
268#define DEFINE_ARRAY_FUNCTIONS(type) \
269 DEFINE_WRITE_FUNCTION(type) \
270 DEFINE_READ_FUNCTION(type) \
271 DEFINE_COMPARE_ARRAY_FUNCTION(type) \
272 DEFINE_CREATE_ARRAY_FUNCTION(type) \
273 DEFINE_TEST_FUNCTION(type)
275#define DEFINE_TIME_SERIES_FUNCTIONS(type) \
276 DEFINE_WRITE_FUNCTION(type) \
277 DEFINE_READ_FUNCTION(type) \
278 DEFINE_COMPARE_TIME_SERIES_FUNCTION(type) \
279 DEFINE_CREATE_TIME_FREQUENCY_SERIES_FUNCTION(type) \
280 DEFINE_TEST_FUNCTION(type)
282#define DEFINE_FREQUENCY_SERIES_FUNCTIONS(type) \
283 DEFINE_WRITE_FUNCTION(type) \
284 DEFINE_READ_FUNCTION(type) \
285 DEFINE_COMPARE_FREQUENCY_SERIES_FUNCTION(type) \
286 DEFINE_CREATE_TIME_FREQUENCY_SERIES_FUNCTION(type) \
287 DEFINE_TEST_FUNCTION(type)
289#define GENERATE_DATA generate_int_data
298#define GENERATE_DATA generate_float_data
302#define GENERATE_DATA generate_complex_data
307#define StringVector LALStringVector
308DEFINE_WRITE_FUNCTION(StringVector)
309DEFINE_READ_FUNCTION(StringVector)
310DEFINE_TEST_FUNCTION(StringVector)
312#define GENERATE_DATA generate_int_data
320#define GENERATE_DATA generate_float_data
324#define GENERATE_DATA generate_complex_data
329#define GENERATE_DATA generate_int_data
337#define GENERATE_DATA generate_float_data
341#define GENERATE_DATA generate_complex_data
346#define GENERATE_DATA generate_float_data
350#define GENERATE_DATA generate_complex_data
355#if defined(GENERATE_HDF5_TEST_FILE)
359static void create_hdf5(
void) {
360 char const *buf =
"La soupe est pr\xc3\xaate.";
362 hid_t file_create = H5Fcreate(TEST_DATA_DIR
"hdf5_attr_utf8.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
363 hid_t fspace = H5Screate(H5S_SCALAR);
364 hid_t memtype_id = H5Tcopy(H5T_C_S1);
365 H5Tset_cset(memtype_id, H5T_CSET_UTF8);
366 H5Tset_size(memtype_id, H5T_VARIABLE);
368 hid_t attr = H5Acreate2(file_create,
"CANONICAL_FILE_BASENAME", memtype_id, fspace, H5P_DEFAULT, H5P_DEFAULT);
370 if(!(H5Awrite(attr, memtype_id, &buf) >= 0)){
371 fprintf(stderr,
"Attribute write fail\n");
374 if(!(H5Sclose(fspace) >= 0)){
375 fprintf(stderr,
"Space close fail\n");
378 if(!(H5Tclose(memtype_id) >= 0)){
379 fprintf(stderr,
"Memtype close fail\n");
383 if(!(H5Aclose(attr) >= 0)){
384 fprintf(stderr,
"Attribute close fail\n");
388 H5Fflush(file_create, H5F_SCOPE_GLOBAL);
389 H5Fclose(file_create);
393static void check_string_reading_from_hdf5_attr(
395 char const* attribute_name,
397 char const* attr_type) {
399 fprintf(stderr,
"Testing HDF5 attribute reading %s...\n", attr_type);
405 fprintf(stderr,
"Attribute length read incorrect\n");
408 char *read_string_back = read_string_back =
XLALCalloc(1, len + 1 );
411 if(strcmp(read_string_back, buf) != 0){
412 fprintf(stderr,
"Read string incorrect '%s'\n", read_string_back);
418 fprintf(stderr,
"Testing HDF5 attribute reading %s... ok!\n", attr_type);
434 test_COMPLEX8Vector();
435 test_COMPLEX16Vector();
446 test_COMPLEX8Array();
447 test_COMPLEX16Array();
449 test_INT2TimeSeries();
450 test_INT4TimeSeries();
451 test_INT8TimeSeries();
452 test_UINT2TimeSeries();
453 test_UINT4TimeSeries();
454 test_UINT8TimeSeries();
455 test_REAL4TimeSeries();
456 test_REAL8TimeSeries();
457 test_COMPLEX8TimeSeries();
458 test_COMPLEX16TimeSeries();
460 test_REAL4FrequencySeries();
461 test_REAL8FrequencySeries();
462 test_COMPLEX8FrequencySeries();
463 test_COMPLEX16FrequencySeries();
465#if defined(GENERATE_HDF5_TEST_FILE)
470 check_string_reading_from_hdf5_attr(
471 TEST_DATA_DIR
"hdf5_attr_ascii.h5",
472 "CANONICAL_FILE_BASENAME",
473 "test long string ascii",
477 check_string_reading_from_hdf5_attr(
478 TEST_DATA_DIR
"hdf5_attr_utf8.h5",
479 "CANONICAL_FILE_BASENAME",
480 "La soupe est pr\xc3\xaate.",
struct tagLALH5File LALH5File
Incomplete type for a HDF5 file.
int XLALH5AttributeQueryStringValue(char *value, size_t size, const LALH5Generic object, const char *key)
LALH5File * XLALH5FileOpen(const char *path, const char *mode)
void XLALH5FileClose(LALH5File *file)
void LALCheckMemoryLeaks(void)
uint16_t UINT2
Two-byte unsigned integer.
char * XLALStringDuplicate(const char *s)
Like strdup but uses LAL allocation routines (free with LALFree).
LALStringVector * XLALCreateEmptyStringVector(UINT4 length)
Create an empty string vector of the given length.
void XLALAbortErrorHandler(const char *func, const char *file, int line, int errnum)
The XLAL error handler that raises SIGABRT.
XLALErrorHandlerType * XLALSetErrorHandler(XLALErrorHandlerType *newHandler)
Sets the error handler to a new handler and returns the old handler.
Vector of type CHAR, see DATATYPE-Vector types for more details.
Multidimentional array of COMPLEX16, see DATATYPE-Array types for more details.
See DATATYPE-FrequencySeries types for documentation.
Time series of COMPLEX16 data, see DATATYPE-TimeSeries types for more details.
Vector of type COMPLEX16, see DATATYPE-Vector types for more details.
Multidimentional array of COMPLEX8, see DATATYPE-Array types for more details.
See DATATYPE-FrequencySeries types for documentation.
Time series of COMPLEX8 data, see DATATYPE-TimeSeries types for more details.
Vector of type COMPLEX8, see DATATYPE-Vector types for more details.
Multidimentional array of INT2, see DATATYPE-Array types for more details.
Time series of INT2 data, see DATATYPE-TimeSeries types for more details.
Vector of type INT2, see DATATYPE-Vector types for more details.
Multidimentional array of INT4, see DATATYPE-Array types for more details.
Time series of INT4 data, see DATATYPE-TimeSeries types for more details.
Vector of type INT4, see DATATYPE-Vector types for more details.
Multidimentional array of INT8, see DATATYPE-Array types for more details.
Time series of INT8 data, see DATATYPE-TimeSeries types for more details.
Vector of type INT8, see DATATYPE-Vector types for more details.
Vector of type CHAR*, ie 'strings', see DATATYPE-Vector types for more details.
UINT4 length
Number of elements in array.
CHAR ** data
Pointer to the data array.
Epoch relative to GPS epoch, see LIGOTimeGPS type for more details.
Multidimentional array of REAL4, see DATATYPE-Array types for more details.
See DATATYPE-FrequencySeries types for documentation.
Time series of REAL4 data, see DATATYPE-TimeSeries types for more details.
Vector of type REAL4, see DATATYPE-Vector types for more details.
Multidimentional array of REAL8, see DATATYPE-Array types for more details.
See DATATYPE-FrequencySeries types for documentation.
Time series of REAL8 data, see DATATYPE-TimeSeries types for more details.
Vector of type REAL8, see DATATYPE-Vector types for more details.
Multidimentional array of UINT2, see DATATYPE-Array types for more details.
Time series of UINT2 data, see DATATYPE-TimeSeries types for more details.
Vector of type UINT2, see DATATYPE-Vector types for more details.
Multidimentional array of UINT4, see DATATYPE-Array types for more details.
Time series of UINT4 data, see DATATYPE-TimeSeries types for more details.
Vector of type UINT4, see DATATYPE-Vector types for more details.
Multidimentional array of UINT8, see DATATYPE-Array types for more details.
Time series of UINT8 data, see DATATYPE-TimeSeries types for more details.
Vector of type UINT8, see DATATYPE-Vector types for more details.
Incomplete type for a pointer to an HDF5 file or group or dataset.
LALH5File * file
Pointer to a LALH5File file.