00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 #ifdef HAVE_CONFIG_H
00087 # include <config.h>
00088 #endif
00089
00090
00112
00113
00114
00115 #if defined HAVE_SETENV && HAVE_SETENV
00116 #if defined HAVE_DECL_SETENV && !HAVE_DECL_SETENV
00117 int setenv(const char *name, const char *value, int overwrite);
00118 #endif
00119 #endif
00120
00121
00122
00123
00124
00125 #include <uves_plot.h>
00126
00127 #include <uves_dump.h>
00128 #include <uves_utils_wrappers.h>
00129 #include <uves_error.h>
00130 #include <uves_msg.h>
00131
00132 #include <irplib_plot.h>
00133 #include <irplib_utils.h>
00134 #include <irplib_access.h>
00135
00136 #include <cpl.h>
00137
00138 #include <stdarg.h>
00139 #include <stdio.h>
00140 #include <string.h>
00141 #include <stdlib.h>
00142
00143
00144
00145
00146 static char *title_string(const char *title, int npoints);
00147
00148
00149
00150 #define MAXTITLELENGTH 10000
00151 #define RECOVER_FROM_ERROR(EXTERNAL_COMMAND) do { \
00152 if (cpl_error_get_code() != CPL_ERROR_NONE) \
00153 { \
00154 uves_msg_error("Could not send plot to " \
00155 "command '%s': " \
00156 "%s in '%s'", \
00157 EXTERNAL_COMMAND, \
00158 cpl_error_get_message(), \
00159 cpl_error_get_where()); \
00160 cpl_error_reset(); \
00161 goto cleanup; \
00162 } } while (false)
00163
00164
00165 static char title[MAXTITLELENGTH];
00166 static bool plotting_enabled = false;
00167
00168
00169 static const char *plotter = "";
00170
00173
00174
00175
00176
00177
00189
00190 cpl_error_code
00191 uves_plot_initialize(const char *plotter_command)
00192 {
00193 char *test_cmd = NULL;
00194 char *first_word = NULL;
00195
00196 plotting_enabled = (strcmp(plotter_command, "no") != 0);
00197
00198
00199
00200
00201
00202 if (plotting_enabled)
00203 {
00204 const char *env = "IRPLIB_PLOTTER";
00205
00206
00207
00208
00209
00210
00211
00212 first_word = uves_sprintf("%s ", plotter_command);
00213
00214 assure( strtok(first_word, " ") != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
00215 "Error splitting string '%s'", first_word);
00216
00217 test_cmd = uves_sprintf("which %s > /dev/null", first_word);
00218
00219 #if defined HAVE_SETENV && HAVE_SETENV
00220
00221 if (setenv(env, plotter_command, 1) != 0)
00222 {
00223 uves_msg_warning("Could not set environment variable '%s'. "
00224 "Plotting disabled!", env);
00225 plotting_enabled = false;
00226 }
00227
00228
00229
00230
00231
00232
00233 else if (system(test_cmd) != 0)
00234 {
00235 uves_msg_debug("Command '%s' returned non-zero", test_cmd);
00236 uves_msg_warning("Command '%s' failed. Plotting disabled!", test_cmd);
00237 plotting_enabled = false;
00238 }
00239 else
00240 {
00241
00242 uves_msg_debug("setenv %s='%s' succeeded", env, plotter_command);
00243 uves_msg_debug("Command '%s' returned zero", test_cmd);
00244
00245 plotter = plotter_command;
00246 }
00247 #else
00248 uves_msg_warning("setenv() is not available on this platform. You have to manually "
00249 "set the environment variable '%s' to '%s'", env, plotter_command);
00250
00251 plotter = plotter_command;
00252
00253 #endif
00254 }
00255
00256 cleanup:
00257 cpl_free(test_cmd);
00258 cpl_free(first_word);
00259
00260 return cpl_error_get_code();
00261 }
00262
00263
00278
00279 cpl_error_code
00280 uves_plot_image_rows(const cpl_image *image, int first_row, int last_row, int step,
00281 const char *xtitle, const char *ytitle, const char *format, ...)
00282 {
00283 va_list al;
00284
00285 char *pre = NULL;
00286 char *options = NULL;
00287 const char *post = "";
00288 cpl_image *thresholded = NULL;
00289
00290 assure( image != NULL, CPL_ERROR_NULL_INPUT, "Null image");
00291 if (xtitle == NULL) xtitle = "";
00292 if (ytitle == NULL) ytitle = "";
00293 assure( 1 <= first_row && first_row <= last_row &&
00294 last_row <= cpl_image_get_size_y(image),
00295 CPL_ERROR_ILLEGAL_INPUT,
00296 "Illegal rows: %d - %d; rows in image = %d",
00297 first_row, last_row, cpl_image_get_size_y(image));
00298
00299 assure( step >= 1, CPL_ERROR_ILLEGAL_INPUT,
00300 "Illegal step size: %d", step);
00301
00302 if (plotting_enabled)
00303 {
00304 const char *pre_format;
00305 int row;
00306
00307
00308 pre_format = "set grid; set xlabel '%s'; set ylabel '%s';";
00309 pre = cpl_calloc(strlen(pre_format) +
00310 strlen(xtitle) + strlen(ytitle) + 1,
00311 sizeof(char));
00312 sprintf(pre, pre_format, xtitle, ytitle);
00313
00314
00315 va_start(al, format);
00316 vsnprintf(title, MAXTITLELENGTH - 1, format, al);
00317 va_end(al);
00318 title[MAXTITLELENGTH - 1] = '\0';
00319
00320 options = title_string(title, cpl_image_get_size_x(image));
00321
00322
00323 thresholded = cpl_image_duplicate(image);
00324 for (row = first_row; row <= last_row; row++)
00325 {
00326 int nx = cpl_image_get_size_x(thresholded);
00327 double median = cpl_image_get_median_window(thresholded,
00328 1, first_row,
00329 nx, last_row);
00330 double stdev = cpl_image_get_stdev_window(thresholded,
00331 1, first_row,
00332 nx, last_row);
00333
00334 double locut = median - 3*stdev;
00335 double hicut = median + 3*stdev;
00336
00337 int x, pis_rejected;
00338
00339 for (x = 1; x <= nx; x++)
00340 {
00341 double data =
00342 cpl_image_get(thresholded, x, row, &pis_rejected);
00343 if (data < locut) data = locut;
00344 if (data > hicut) data = hicut;
00345 cpl_image_set(thresholded, x, row, data);
00346 }
00347 }
00348
00349 irplib_image_row_plot(pre,
00350 (strcmp(options, "t '%s'") == 0) ? "" : options,
00351 post,
00352 thresholded,
00353 first_row, last_row, step);
00354
00355 RECOVER_FROM_ERROR(plotter);
00356 }
00357
00358 cleanup:
00359 uves_free_image(&thresholded);
00360 cpl_free(pre);
00361 cpl_free(options);
00362
00363 return cpl_error_get_code();
00364 }
00365
00366
00384
00385 cpl_error_code
00386 uves_plot_image_columns(const cpl_image *image, int first_column, int last_column, int step,
00387 const char *xtitle, const char *ytitle, const char *format, ...)
00388 {
00389 va_list al;
00390
00391 char *pre = NULL;
00392 char *options = NULL;
00393 const char *post = "";
00394 cpl_image *thresholded = NULL;
00395
00396 assure( image != NULL, CPL_ERROR_NULL_INPUT, "Null image");
00397 if (xtitle == NULL) xtitle = "";
00398 if (ytitle == NULL) ytitle = "";
00399 assure( 1 <= first_column && first_column <= last_column &&
00400 last_column <= cpl_image_get_size_x(image),
00401 CPL_ERROR_ILLEGAL_INPUT,
00402 "Illegal columns: %d - %d; columns in image = %d",
00403 first_column, last_column, cpl_image_get_size_x(image));
00404
00405 assure( step >= 1, CPL_ERROR_ILLEGAL_INPUT,
00406 "Illegal step size: %d", step);
00407
00408 if (plotting_enabled)
00409 {
00410 const char *pre_format;
00411 int col;
00412
00413
00414 pre_format = "set grid; set xlabel '%s'; set ylabel '%s';";
00415 pre = cpl_calloc(strlen(pre_format) +
00416 strlen(xtitle) + strlen(ytitle) + 1,
00417 sizeof(char));
00418 sprintf(pre, pre_format, xtitle, ytitle);
00419
00420 va_start(al, format);
00421 vsnprintf(title, MAXTITLELENGTH - 1, format, al);
00422 va_end(al);
00423 title[MAXTITLELENGTH - 1] = '\0';
00424
00425 options = title_string(title, cpl_image_get_size_y(image));
00426
00427
00428 thresholded = cpl_image_duplicate(image);
00429 for (col = first_column; col <= last_column; col++)
00430 {
00431 int ny = cpl_image_get_size_x(thresholded);
00432 double median = cpl_image_get_median_window(thresholded,
00433 first_column, 1,
00434 last_column, ny);
00435 double stdev = cpl_image_get_stdev_window(thresholded,
00436 first_column, 1,
00437 last_column, ny);
00438
00439 double locut = median - 3*stdev;
00440 double hicut = median + 3*stdev;
00441
00442 int y, pis_rejected;
00443
00444 for (y = 1; y <= ny; y++)
00445 {
00446 double data = cpl_image_get(thresholded, col, y, &pis_rejected);
00447 if (data < locut) data = locut;
00448 if (data > hicut) data = hicut;
00449 cpl_image_set(thresholded, col, y, data);
00450 }
00451 }
00452
00453
00454 check( irplib_image_col_plot(pre,
00455 (strcmp(options, "t '%s'") == 0) ? "" : options,
00456 post,
00457 image,
00458 first_column, last_column, step),
00459 "Error plotting image");
00460
00461 RECOVER_FROM_ERROR(plotter);
00462 }
00463
00464 cleanup:
00465 uves_free_image(&thresholded);
00466 cpl_free(pre);
00467 cpl_free(options);
00468
00469 return cpl_error_get_code();
00470 }
00471
00472
00486
00487 void
00488 uves_plot_bivectors(cpl_bivector **bivectors, char **titles,
00489 int N, const char *xtitle,
00490 const char *ytitle)
00491 {
00492 char *pre = NULL;
00493 char **options = NULL;
00494 const char *post = "";
00495
00496 options = cpl_calloc(N, sizeof(char *));
00497 assure_mem( options );
00498
00499 if (plotting_enabled)
00500 {
00501 int npoints, i;
00502 cpl_bivector *temp;
00503 char *temps;
00504
00505
00506
00507 npoints = 0;
00508 for (i = 0; i < N; i++)
00509 {
00510 npoints += cpl_bivector_get_size(bivectors[i]);
00511 }
00512 for (i = 0; i < N; i++)
00513 {
00514 options[i] = title_string(titles[i], npoints);
00515 }
00516
00517
00518 {
00519 double datamax = cpl_vector_get_max(irplib_bivector_get_y(bivectors[0]));
00520 double datamin = cpl_vector_get_min(irplib_bivector_get_y(bivectors[0]));
00521
00522 double locut = datamin - 0.2*(datamax-datamin);
00523 double hicut = datamax + 0.2*(datamax-datamin);
00524
00525 for (i = 0; i < N; i++)
00526 {
00527 int j;
00528 for (j = 0; j < cpl_bivector_get_size(bivectors[i]); j++)
00529 {
00530 if (irplib_bivector_get_y_data(bivectors[i])[j] < locut)
00531 {
00532 irplib_bivector_get_y_data(bivectors[i])[j] = locut;
00533 }
00534 if (irplib_bivector_get_y_data(bivectors[i])[j] > hicut)
00535 {
00536 irplib_bivector_get_y_data(bivectors[i])[j] = hicut;
00537 }
00538 }
00539 }
00540 }
00541
00542
00543 temp = bivectors[0];
00544 bivectors[0] = bivectors[N-1];
00545 bivectors[N-1] = temp;
00546
00547 temps = options[0];
00548 options[0] = options[N-1];
00549 options[N-1] = temps;
00550
00551 pre = uves_sprintf(
00552 "set grid; set xlabel '%s'; set ylabel '%s';", xtitle, ytitle);
00553
00554 irplib_bivectors_plot(pre,
00555 (const char **)options,
00556 post,
00557 (const cpl_bivector **)bivectors, N);
00558
00559 RECOVER_FROM_ERROR(plotter);
00560 }
00561
00562 cleanup:
00563 cpl_free(pre);
00564 {
00565 int i;
00566 for (i = 0; i < N; i++)
00567 {
00568 cpl_free(options[i]);
00569 }
00570 }
00571 cpl_free(options);
00572 return;
00573 }
00574
00575
00591
00592 cpl_error_code
00593 uves_plot_table(const cpl_table *table, const char *colx, const char *coly,
00594 const char *format, ...)
00595 {
00596 va_list al;
00597
00598 char *pre = NULL;
00599 char *options = NULL;
00600 const char *post = "";
00601 cpl_table *thresholded = NULL;
00602
00603 assure( table != NULL, CPL_ERROR_NULL_INPUT, "Null table");
00604 assure( colx != NULL, CPL_ERROR_NULL_INPUT, "Null x column");
00605 assure( coly != NULL, CPL_ERROR_NULL_INPUT, "Null y column");
00606 assure( cpl_table_has_column(table, colx), CPL_ERROR_ILLEGAL_INPUT,
00607 "No such column: '%s'", colx);
00608 assure( cpl_table_has_column(table, coly), CPL_ERROR_ILLEGAL_INPUT,
00609 "No such column: '%s'", coly);
00610
00611 assure( cpl_table_get_column_type(table, colx) == CPL_TYPE_INT ||
00612 cpl_table_get_column_type(table, colx) == CPL_TYPE_FLOAT ||
00613 cpl_table_get_column_type(table, colx) == CPL_TYPE_DOUBLE,
00614 CPL_ERROR_TYPE_MISMATCH,
00615 "Column '%s' has type '%s'. Numerical type expected",
00616 colx,
00617 uves_tostring_cpl_type(cpl_table_get_column_type(table, colx)));
00618
00619 assure( cpl_table_get_column_type(table, coly) == CPL_TYPE_INT ||
00620 cpl_table_get_column_type(table, coly) == CPL_TYPE_FLOAT ||
00621 cpl_table_get_column_type(table, coly) == CPL_TYPE_DOUBLE,
00622 CPL_ERROR_TYPE_MISMATCH,
00623 "Column '%s' has type '%s'. Numerical type expected",
00624 coly,
00625 uves_tostring_cpl_type(cpl_table_get_column_type(table, coly)));
00626
00627 if (plotting_enabled)
00628 {
00629 const char *pre_format;
00630
00631
00632 va_start(al, format);
00633 vsnprintf(title, MAXTITLELENGTH - 1, format, al);
00634 va_end(al);
00635 title[MAXTITLELENGTH - 1] = '\0';
00636
00637 options = title_string(title, cpl_table_get_nrow(table));
00638
00639
00640 pre_format = "set grid; set xlabel '%s'; set ylabel '%s';";
00641 pre = cpl_calloc(strlen(pre_format) + strlen(colx) + strlen(coly) + 1,
00642 sizeof(char));
00643
00644 sprintf(pre, pre_format, colx, coly);
00645
00646
00647
00648 {
00649 double median, sigma, locut, hicut;
00650 int i;
00651
00652 median = cpl_table_get_column_median(table, coly);
00653 sigma = cpl_table_get_column_stdev(table, coly);
00654
00655 locut = median - 3*sigma;
00656 hicut = median + 3*sigma;
00657
00658
00659 thresholded = cpl_table_new(cpl_table_get_nrow(table));
00660 cpl_table_duplicate_column(thresholded, coly, table, coly);
00661 cpl_table_duplicate_column(thresholded, colx, table, colx);
00662
00663 for (i = 0; i < cpl_table_get_nrow(thresholded); i++)
00664 {
00665 double data = cpl_table_get(thresholded, coly, i, NULL);
00666
00667 if (data < locut && data > hicut)
00668 {
00669 cpl_table_set_invalid(thresholded, coly, i);
00670 }
00671 }
00672
00673 }
00674
00675 irplib_table_plot(pre,
00676 (strcmp(options, "t '%s'") == 0) ? "" : options,
00677 post,
00678 thresholded, colx, coly);
00679
00680 RECOVER_FROM_ERROR(plotter);
00681 }
00682
00683 cleanup:
00684 uves_free_table(&thresholded);
00685 cpl_free(pre);
00686 cpl_free(options);
00687
00688 return cpl_error_get_code();
00689 }
00690
00691
00692
00702
00703 static char *
00704 title_string(const char *plot_title, int npoints)
00705 {
00706
00707
00708
00709 const char *options = (npoints > 100) ?
00710 "w points pointsize 1" :
00711 "w linespoints pointsize 1";
00712
00713
00714 size_t length = strlen("t '' ") + strlen(plot_title) + strlen(options) + 1;
00715 char *result = cpl_calloc(length, sizeof(char));
00716
00717 snprintf(result, length, "t '%s' %s", plot_title, options);
00718
00719 return result;
00720 }
00721