commit 64af11c1a4866444225abb8dd3db2fc7280c8d53
parent 46552ba425acb9d9be534d66301bbb9b92482f07
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 19 Apr 2017 15:29:17 +0200
The parsed spectrum does not need to be sorted anymore
Sort the spectrum after the parsing of its data.
Diffstat:
3 files changed, 120 insertions(+), 12 deletions(-)
diff --git a/cmake/parser/CMakeLists.txt b/cmake/parser/CMakeLists.txt
@@ -108,6 +108,7 @@ if(NOT NO_TEST)
new_test(test_solparser7)
new_test(test_solparser8)
new_test(test_solparser_normal_map)
+ new_test(test_solparser_spectrum)
rcmake_copy_runtime_libraries(test_solparser)
endif()
diff --git a/src/parser/solparser_spectrum.c b/src/parser/solparser_spectrum.c
@@ -20,12 +20,22 @@
/*******************************************************************************
* Helper functions
******************************************************************************/
+static int
+cmp_spectrum_data(const void* op0, const void* op1)
+{
+ const struct solparser_spectrum_data* a = op0;
+ const struct solparser_spectrum_data* b = op1;
+ ASSERT(a && b);
+ if(a->wavelength < b->wavelength) return -1;
+ if(a->wavelength > b->wavelength) return 1;
+ return 0;
+}
+
static res_T
parse_spectrum_data
(struct solparser* parser,
yaml_document_t* doc,
const yaml_node_t* sdata,
- double* last_wl,
struct solparser_spectrum_data* spectrum_data)
{
enum { DATA, WAVELENGTH };
@@ -67,16 +77,8 @@ parse_spectrum_data
res = parse_real(parser, val, 0, DBL_MAX, &spectrum_data->data);
} else if(!strcmp((char*)key->data.scalar.value, "wavelength")) {
SETUP_MASK(WAVELENGTH, "wavelength");
- res = parse_real(parser, val, nextafter(*last_wl, DBL_MAX), DBL_MAX,
+ res = parse_real(parser, val, nextafter(0, DBL_MAX), DBL_MAX,
&spectrum_data->wavelength);
- if(*last_wl >= spectrum_data->wavelength) {
- ASSERT(res != RES_OK);
- log_err(parser, key,
- "spectrum with non-increasing wavelengths (%g after %g).\n",
- spectrum_data->wavelength,
- *last_wl);
- }
- *last_wl = spectrum_data->wavelength;
} else {
log_err(parser, key, "unknown spectrum data parameter `%s'.\n",
key->data.scalar.value);
@@ -118,7 +120,6 @@ parse_spectrum
{
intptr_t i, n;
res_T res = RES_OK;
- double last_wl = 0;
ASSERT(doc && spectrum && data);
if(spectrum->type != YAML_SEQUENCE_NODE) {
@@ -140,10 +141,32 @@ parse_spectrum
sdata = yaml_document_get_node(doc, spectrum->data.sequence.items.start[i]);
spectrum_data = darray_spectrum_data_data_get(data) + i;
- res = parse_spectrum_data(parser, doc, sdata, &last_wl, spectrum_data);
+ res = parse_spectrum_data(parser, doc, sdata, spectrum_data);
if(res != RES_OK) goto error;
}
+ if(n == 1) goto exit;
+
+ qsort
+ (darray_spectrum_data_data_get(data),
+ darray_spectrum_data_size_get(data),
+ sizeof(struct solparser_spectrum_data),
+ cmp_spectrum_data);
+
+ FOR_EACH(i, 1, n) {
+ const struct solparser_spectrum_data* a;
+ const struct solparser_spectrum_data* b;
+ a = darray_spectrum_data_cdata_get(data) + i - 1;
+ b = darray_spectrum_data_cdata_get(data) + i;
+ ASSERT(cmp_spectrum_data(a, b) <= 0);
+ if(a->wavelength == b->wavelength) {
+ log_err(parser, spectrum,
+ "duplicated spectrum entry for the wavelength %g\n", a->wavelength);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ }
+
exit:
return res;
error:
diff --git a/src/parser/test_solparser_spectrum.c b/src/parser/test_solparser_spectrum.c
@@ -0,0 +1,84 @@
+/* Copyright (C) CNRS 2016-2017
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "solparser.h"
+#include "solparser_sun.h"
+#include "test_solstice_utils.h"
+
+static void
+test_sun(struct solparser* parser)
+{
+ const struct solparser_sun* sun;
+ FILE* stream;
+ size_t i;
+
+ NCHECK(stream = tmpfile(), NULL);
+
+ fprintf(stream, "- sun:\n");
+ fprintf(stream, " dni: 123.456\n");
+ fprintf(stream, " spectrum:\n");
+ fprintf(stream, " - { wavelength: 2, data: 2 }\n");
+ fprintf(stream, " - { wavelength: 1, data: 1 }\n");
+ fprintf(stream, " - { wavelength: 8, data: 8 }\n");
+ fprintf(stream, " - { wavelength: 3, data: 3 }\n");
+ fprintf(stream, " - { wavelength: 5, data: 5 }\n");
+ fprintf(stream, " - { wavelength: 9, data: 9 }\n");
+ fprintf(stream, " - { wavelength: 6, data: 6 }\n");
+ fprintf(stream, " - { wavelength: 7, data: 7 }\n");
+ fprintf(stream, " - { wavelength: 4, data: 4 }\n");
+ fprintf(stream, "- material: &matte { matte: { reflectivity: 1 } }\n");
+ fprintf(stream, "- entity:\n");
+ fprintf(stream, " name: foo bar\n");
+ fprintf(stream, " primary: 0\n");
+ fprintf(stream, " geometry: [{sphere: {radius: 1}, material: *matte}]\n");
+ rewind(stream);
+
+ CHECK(solparser_setup(parser, NULL, stream), RES_OK);
+ CHECK(solparser_load(parser), RES_OK);
+
+ sun = solparser_get_sun(parser);
+ CHECK(sun->dni, 123.456);
+ CHECK(sun->radang_distrib_type, SOLPARSER_SUN_RADANG_DISTRIB_DIRECTIONAL);
+ CHECK(darray_spectrum_data_size_get(&sun->spectrum), 9);
+
+ FOR_EACH(i, 0, darray_spectrum_data_size_get(&sun->spectrum)) {
+ CHECK(darray_spectrum_data_cdata_get(&sun->spectrum)[i].wavelength, i+1);
+ CHECK(darray_spectrum_data_cdata_get(&sun->spectrum)[i].wavelength, i+1);
+ }
+
+ CHECK(solparser_load(parser), RES_BAD_OP);
+ fclose(stream);
+}
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct solparser* parser;
+ (void)argc, (void)argv;
+
+ CHECK(mem_init_proxy_allocator(&allocator, &mem_default_allocator), RES_OK);
+ CHECK(solparser_create(&allocator, &parser), RES_OK);
+
+ test_sun(parser);
+
+ solparser_ref_put(parser);
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHECK(mem_allocated_size(), 0);
+ return 0;
+}
+