commit a6f399bea429efc48db8a6f8cec5e5979c398963
parent 3d21cacdfd8f31136192afeab00381921c62fc4b
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Sat, 24 Sep 2016 15:04:23 +0200
BugFix: management of failed realisations
They are now replayed untill success or general failure
Diffstat:
8 files changed, 54 insertions(+), 48 deletions(-)
diff --git a/src/ssol_solver.c b/src/ssol_solver.c
@@ -671,30 +671,43 @@ ssol_solve
res = init_realisation(scene, rng, output, &rs);
if (res != RES_OK) goto error;
- FOR_EACH(r, 0, realisations_count) {
- reset_realisation(r, &rs);
- sample_point_on_primary_mirror(&rs);
- sample_input_sundir(&rs);
- sample_wavelength(&rs);
-
- /* check if the point receives sun light */
- if (receive_sunlight(&rs)) {
- /* start propagating from mirror */
- do {
- if (RES_OK != setup_next_segment(&rs)) {
- rs.end = TERM_ERR;
- } else {
- propagate(&rs);
- }
- } while (rs.end == TERM_NONE);
- }
-
- /* propagation ended */
- fprintf(output, "Realisation %u success mask: 0x%0x\n",
- (unsigned)r, rs.success_mask);
- fprintf(output, "Realisation %u end: %s\n\n",
- (unsigned)r, END_TEXT[rs.end]);
+ for (r = 0; r < realisations_count; ) {
+ fpos_t real_start;
+ int err_count = 0;
+ CHECK(fgetpos(output, &real_start), 0);
+ do {
+ reset_realisation(r, &rs);
+ sample_point_on_primary_mirror(&rs);
+ sample_input_sundir(&rs);
+ sample_wavelength(&rs);
+
+ /* check if the point receives sun light */
+ if (receive_sunlight(&rs)) {
+ /* start propagating from mirror */
+ do {
+ if (RES_OK != setup_next_segment(&rs)) {
+ rs.end = TERM_ERR;
+ }
+ else {
+ propagate(&rs);
+ }
+ } while (rs.end == TERM_NONE);
+ }
+ /* propagation ended */
+ fprintf(output, "Realisation %u success mask: 0x%0x\n",
+ (unsigned) r, rs.success_mask);
+ fprintf(output, "Realisation %u end: %s\n\n",
+ (unsigned) r, END_TEXT[rs.end]);
+
+ /* must retry failed realisations */
+ if (rs.end == TERM_ERR) {
+ CHECK(fsetpos(output, &real_start), 0);
+ if (++err_count > 10) goto error;
+ }
+ else r++;
+ } while (rs.end == TERM_ERR);
}
+ /* TODO: overwrite trailing chars if canceled realizations wrote past the current fpos */
exit:
release_realisation(&rs);
diff --git a/src/test_ssol_postprocess.h b/src/test_ssol_postprocess.h
@@ -20,12 +20,11 @@
#include <math.h>
static INLINE res_T
-pp_sum(FILE* f, const char* target, double* mean, double* std)
+pp_sum(FILE* f, const char* target, const size_t count, double* mean, double* std)
{
double sum = 0, sum2 = 0, var;
- size_t cpt = 0;
char expect_tok[256];
- ASSERT(f && target && mean && std);
+ ASSERT(f && target && mean && std && count);
snprintf(expect_tok, 256, "'%s':", target);
rewind(f);
while (!feof(f)) {
@@ -33,24 +32,18 @@ pp_sum(FILE* f, const char* target, double* mean, double* std)
if (fgets(buf, 256, f)) {
char tok[256];
double w;
- if(2 == sscanf(buf, "Receiver %s %*f %*f %*f %lf", tok, &w)) {
+ if (2 == sscanf(buf, "Receiver %s %*f %*f %*f %lf", tok, &w)) {
if (strcmp(tok, expect_tok)) continue;
sum += w;
sum2 += w * w;
}
- else if (1 == sscanf(buf, "Realisation %*d %s:", tok)) {
- if (strcmp(tok, "end:")) continue;
- cpt++;
- }
}
}
- if (cpt) {
- *mean = sum / cpt;
- var = (sum2 / cpt - *mean * *mean);
- *std = var > 0 ? sqrt(var / cpt) : 0;
- return RES_OK;
- }
- return RES_UNKNOWN_ERR;
+
+ *mean = sum / count;
+ var = (sum2 / count - *mean * *mean);
+ *std = var > 0 ? sqrt(var / count) : 0;
+ return RES_OK;
}
#endif /* TEST_SSOL_POSTPROCESS_H */
diff --git a/src/test_ssol_solver1.c b/src/test_ssol_solver1.c
@@ -192,7 +192,7 @@ main(int argc, char** argv)
CHECK(!tmp, 0);
#define N 5000
CHECK(ssol_solve(scene, rng, N, tmp), RES_OK);
- CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK);
+ CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK);
logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std);
#define DNI_cos (1000 * cos(PI / 4))
CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 1e-2), 1);
@@ -209,7 +209,7 @@ main(int argc, char** argv)
tmp = tmpfile();
CHECK(ssol_solve(scene, rng, N, tmp), RES_OK);
- CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK);
+ CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK);
logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std);
CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 1e-4), 1);
CHECK(eq_eps(std, 0, 1e-4), 1);
@@ -224,7 +224,7 @@ main(int argc, char** argv)
NCHECK(tmp = tmpfile(), 0);
CHECK(ssol_solve(scene, rng, N, tmp), RES_OK);
- CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK);
+ CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK);
logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std);
CHECK(fclose(tmp), 0);
CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 1e-4), 1);
@@ -243,7 +243,7 @@ main(int argc, char** argv)
NCHECK(tmp = tmpfile(), 0);
CHECK(ssol_solve(scene, rng, N, tmp), RES_OK);
- CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK);
+ CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK);
logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std);
CHECK(fclose(tmp), 0);
#define K (exp(-0.1 * 2 * sqrt(2)))
@@ -262,7 +262,7 @@ main(int argc, char** argv)
CHECK(ssol_spectrum_setup(abs, wavelengths, ka, 2), RES_OK);
NCHECK(tmp = tmpfile(), 0);
CHECK(ssol_solve(scene, rng, N, tmp), RES_OK);
- CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK);
+ CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK);
logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std);
CHECK(fclose(tmp), 0);
#define K2 (exp(-0.121 * 2 * sqrt(2)))
diff --git a/src/test_ssol_solver2.c b/src/test_ssol_solver2.c
@@ -179,7 +179,7 @@ main(int argc, char** argv)
tmp = tmpfile();
#define N 10000
CHECK(ssol_solve(scene, rng, N, tmp), RES_OK);
- CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK);
+ CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK);
logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std);
#define DNI_cos (1000 * cos(PI / 4))
CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 1e-4), 1);
diff --git a/src/test_ssol_solver2b.c b/src/test_ssol_solver2b.c
@@ -184,7 +184,7 @@ main(int argc, char** argv)
tmp = tmpfile();
#define N 10000
CHECK(ssol_solve(scene, rng, N, tmp), RES_OK);
- CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK);
+ CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK);
logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std);
#define DNI_cos (1000 * cos(PI / 4))
CHECK(eq_eps(m, 2 * DNI_cos, 2 * DNI_cos * 1e-2), 1);
diff --git a/src/test_ssol_solver3.c b/src/test_ssol_solver3.c
@@ -140,7 +140,7 @@ main(int argc, char** argv)
tmp = tmpfile();
#define N 10000
CHECK(ssol_solve(scene, rng, N, tmp), RES_OK);
- CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK);
+ CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK);
logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std);
#define DNI_cos (1000 * cos(PI / 4))
CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 2e-1), 1);
diff --git a/src/test_ssol_solver4.c b/src/test_ssol_solver4.c
@@ -140,7 +140,7 @@ main(int argc, char** argv)
tmp = tmpfile();
#define N 10000
CHECK(ssol_solve(scene, rng, N, tmp), RES_OK);
- CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK);
+ CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK);
logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std);
#define DNI_cos (1000 * cos(0))
CHECK(eq_eps(m, 400 * DNI_cos, 1), 1);
diff --git a/src/test_ssol_solver5.c b/src/test_ssol_solver5.c
@@ -140,7 +140,7 @@ main(int argc, char** argv)
tmp = tmpfile();
#define N 10000
CHECK(ssol_solve(scene, rng, N, tmp), RES_OK);
- CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK);
+ CHECK(pp_sum(tmp, "cible", N, &m, &std), RES_OK);
logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std);
#define DNI_cos (1000 * cos(0))
CHECK(eq_eps(m, 400 * DNI_cos, 20), 1);