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