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
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 #ifdef HAVE_CONFIG_H
00105 # include <config.h>
00106 #endif
00107
00108
00130
00131
00132
00133 #if defined HAVE_SETENV && HAVE_SETENV
00134 #if defined HAVE_DECL_SETENV && !HAVE_DECL_SETENV
00135 int setenv(const char *name, const char *value, int overwrite);
00136 #endif
00137 #endif
00138
00139
00140
00141
00142
00143 #include <uves_plot.h>
00144
00145 #include <uves_dump.h>
00146 #include <uves_utils_wrappers.h>
00147 #include <uves_error.h>
00148 #include <uves_msg.h>
00149
00150 #include <irplib_utils.h>
00151
00152 #include <cpl.h>
00153
00154 #include <stdarg.h>
00155 #include <stdio.h>
00156 #include <string.h>
00157 #include <stdlib.h>
00158
00159
00160
00161
00162 static char *title_string(const char *title, int npoints);
00163
00164
00165
00166 #define MAXTITLELENGTH 10000
00167 #define RECOVER_FROM_ERROR(EXTERNAL_COMMAND) do { \
00168 if (cpl_error_get_code() != CPL_ERROR_NONE) \
00169 { \
00170 uves_msg_error("Could not send plot to " \
00171 "command '%s': " \
00172 "%s in '%s'", \
00173 EXTERNAL_COMMAND, \
00174 cpl_error_get_message(), \
00175 cpl_error_get_where()); \
00176 cpl_error_reset(); \
00177 goto cleanup; \
00178 } } while (false)
00179
00180
00181 static char title[MAXTITLELENGTH];
00182 static bool plotting_enabled = false;
00183
00184
00185 static const char *plotter = "";
00186
00189
00190
00191
00192
00193
00205
00206 cpl_error_code
00207 uves_plot_initialize(const char *plotter_command)
00208 {
00209 char *test_cmd = NULL;
00210 char *first_word = NULL;
00211
00212 plotting_enabled = (strcmp(plotter_command, "no") != 0);
00213
00214
00215
00216
00217
00218 if (plotting_enabled)
00219 {
00220 const char *env = "CPL_PLOTTER";
00221
00222
00223
00224
00225
00226
00227
00228 first_word = uves_sprintf("%s ", plotter_command);
00229
00230 assure( strtok(first_word, " ") != NULL, CPL_ERROR_ILLEGAL_OUTPUT,
00231 "Error splitting string '%s'", first_word);
00232
00233 test_cmd = uves_sprintf("which %s > /dev/null", first_word);
00234
00235 #if defined HAVE_SETENV && HAVE_SETENV
00236
00237 if (setenv(env, plotter_command, 1) != 0)
00238 {
00239 uves_msg_warning("Could not set environment variable '%s'. "
00240 "Plotting disabled!", env);
00241 plotting_enabled = false;
00242 }
00243
00244
00245
00246
00247
00248
00249 else if (system(test_cmd) != 0)
00250 {
00251 uves_msg_debug("Command '%s' returned non-zero", test_cmd);
00252 uves_msg_warning("Command '%s' failed. Plotting disabled!", test_cmd);
00253 plotting_enabled = false;
00254 }
00255 else
00256 {
00257
00258 uves_msg_debug("setenv %s='%s' succeeded", env, plotter_command);
00259 uves_msg_debug("Command '%s' returned zero", test_cmd);
00260
00261 plotter = plotter_command;
00262 }
00263 #else
00264 uves_msg_warning("setenv() is not available on this platform. You have to manually "
00265 "set the environment variable '%s' to '%s'", env, plotter_command);
00266
00267 plotter = plotter_command;
00268
00269 #endif
00270 }
00271
00272 cleanup:
00273 cpl_free(test_cmd);
00274 cpl_free(first_word);
00275
00276 return cpl_error_get_code();
00277 }
00278
00279
00294
00295 cpl_error_code
00296 uves_plot_image_rows(const cpl_image *image, int first_row, int last_row, int step,
00297 const char *xtitle, const char *ytitle, const char *format, ...)
00298 {
00299 va_list al;
00300
00301 char *pre = NULL;
00302 char *options = NULL;
00303 const char *post = "";
00304 cpl_image *thresholded = NULL;
00305
00306 assure( image != NULL, CPL_ERROR_NULL_INPUT, "Null image");
00307 if (xtitle == NULL) xtitle = "";
00308 if (ytitle == NULL) ytitle = "";
00309 assure( 1 <= first_row && first_row <= last_row &&
00310 last_row <= cpl_image_get_size_y(image),
00311 CPL_ERROR_ILLEGAL_INPUT,
00312 "Illegal rows: %d - %d; rows in image = %" CPL_SIZE_FORMAT "",
00313 first_row, last_row, cpl_image_get_size_y(image));
00314
00315 assure( step >= 1, CPL_ERROR_ILLEGAL_INPUT,
00316 "Illegal step size: %d", step);
00317
00318 if (plotting_enabled)
00319 {
00320 const char *pre_format;
00321 int row;
00322
00323
00324 pre_format = "set grid; set xlabel '%s'; set ylabel '%s';";
00325 pre = cpl_calloc(strlen(pre_format) +
00326 strlen(xtitle) + strlen(ytitle) + 1,
00327 sizeof(char));
00328 sprintf(pre, pre_format, xtitle, ytitle);
00329
00330
00331 va_start(al, format);
00332 vsnprintf(title, MAXTITLELENGTH - 1, format, al);
00333 va_end(al);
00334 title[MAXTITLELENGTH - 1] = '\0';
00335
00336 options = title_string(title, cpl_image_get_size_x(image));
00337
00338
00339 thresholded = cpl_image_duplicate(image);
00340 for (row = first_row; row <= last_row; row++)
00341 {
00342 int nx = cpl_image_get_size_x(thresholded);
00343 double median = cpl_image_get_median_window(thresholded,
00344 1, first_row,
00345 nx, last_row);
00346 double stdev = cpl_image_get_stdev_window(thresholded,
00347 1, first_row,
00348 nx, last_row);
00349
00350 double locut = median - 3*stdev;
00351 double hicut = median + 3*stdev;
00352
00353 int x, pis_rejected;
00354
00355 for (x = 1; x <= nx; x++)
00356 {
00357 double data =
00358 cpl_image_get(thresholded, x, row, &pis_rejected);
00359 if (data < locut) data = locut;
00360 if (data > hicut) data = hicut;
00361 cpl_image_set(thresholded, x, row, data);
00362 }
00363 }
00364
00365 cpl_plot_image_row(pre,
00366 (strcmp(options, "t '%s'") == 0) ? "" : options,
00367 post,
00368 thresholded,
00369 first_row, last_row, step);
00370
00371 RECOVER_FROM_ERROR(plotter);
00372 }
00373
00374 cleanup:
00375 uves_free_image(&thresholded);
00376 cpl_free(pre);
00377 cpl_free(options);
00378
00379 return cpl_error_get_code();
00380 }
00381
00382
00400
00401 cpl_error_code
00402 uves_plot_image_columns(const cpl_image *image, int first_column, int last_column, int step,
00403 const char *xtitle, const char *ytitle, const char *format, ...)
00404 {
00405 va_list al;
00406
00407 char *pre = NULL;
00408 char *options = NULL;
00409 const char *post = "";
00410 cpl_image *thresholded = NULL;
00411
00412 assure( image != NULL, CPL_ERROR_NULL_INPUT, "Null image");
00413 if (xtitle == NULL) xtitle = "";
00414 if (ytitle == NULL) ytitle = "";
00415 assure( 1 <= first_column && first_column <= last_column &&
00416 last_column <= cpl_image_get_size_x(image),
00417 CPL_ERROR_ILLEGAL_INPUT,
00418 "Illegal columns: %d - %d; columns in image = %" CPL_SIZE_FORMAT "",
00419 first_column, last_column, cpl_image_get_size_x(image));
00420
00421 assure( step >= 1, CPL_ERROR_ILLEGAL_INPUT,
00422 "Illegal step size: %d", step);
00423
00424 if (plotting_enabled)
00425 {
00426 const char *pre_format;
00427 int col;
00428
00429
00430 pre_format = "set grid; set xlabel '%s'; set ylabel '%s';";
00431 pre = cpl_calloc(strlen(pre_format) +
00432 strlen(xtitle) + strlen(ytitle) + 1,
00433 sizeof(char));
00434 sprintf(pre, pre_format, xtitle, ytitle);
00435
00436 va_start(al, format);
00437 vsnprintf(title, MAXTITLELENGTH - 1, format, al);
00438 va_end(al);
00439 title[MAXTITLELENGTH - 1] = '\0';
00440
00441 options = title_string(title, cpl_image_get_size_y(image));
00442
00443
00444 thresholded = cpl_image_duplicate(image);
00445 for (col = first_column; col <= last_column; col++)
00446 {
00447 int ny = cpl_image_get_size_x(thresholded);
00448 double median = cpl_image_get_median_window(thresholded,
00449 first_column, 1,
00450 last_column, ny);
00451 double stdev = cpl_image_get_stdev_window(thresholded,
00452 first_column, 1,
00453 last_column, ny);
00454
00455 double locut = median - 3*stdev;
00456 double hicut = median + 3*stdev;
00457
00458 int y, pis_rejected;
00459
00460 for (y = 1; y <= ny; y++)
00461 {
00462 double data = cpl_image_get(thresholded, col, y, &pis_rejected);
00463 if (data < locut) data = locut;
00464 if (data > hicut) data = hicut;
00465 cpl_image_set(thresholded, col, y, data);
00466 }
00467 }
00468
00469
00470 check( cpl_plot_image_col(pre,
00471 (strcmp(options, "t '%s'") == 0) ? "" : options,
00472 post,
00473 image,
00474 first_column, last_column, step),
00475 "Error plotting image");
00476
00477 RECOVER_FROM_ERROR(plotter);
00478 }
00479
00480 cleanup:
00481 uves_free_image(&thresholded);
00482 cpl_free(pre);
00483 cpl_free(options);
00484
00485 return cpl_error_get_code();
00486 }
00487
00488
00502
00503 void
00504 uves_plot_bivectors(cpl_bivector **bivectors, char **titles,
00505 int N, const char *xtitle,
00506 const char *ytitle)
00507 {
00508 char *pre = NULL;
00509 char **options = NULL;
00510 const char *post = "";
00511
00512 options = cpl_calloc(N, sizeof(char *));
00513 assure_mem( options );
00514
00515 if (plotting_enabled)
00516 {
00517 int npoints, i;
00518 cpl_bivector *temp;
00519 char *temps;
00520
00521
00522
00523 npoints = 0;
00524 for (i = 0; i < N; i++)
00525 {
00526 npoints += cpl_bivector_get_size(bivectors[i]);
00527 }
00528 for (i = 0; i < N; i++)
00529 {
00530 options[i] = title_string(titles[i], npoints);
00531 }
00532
00533
00534 {
00535 double datamax = cpl_vector_get_max(cpl_bivector_get_y(bivectors[0]));
00536 double datamin = cpl_vector_get_min(cpl_bivector_get_y(bivectors[0]));
00537
00538 double locut = datamin - 0.2*(datamax-datamin);
00539 double hicut = datamax + 0.2*(datamax-datamin);
00540
00541 for (i = 0; i < N; i++)
00542 {
00543 int j;
00544 for (j = 0; j < cpl_bivector_get_size(bivectors[i]); j++)
00545 {
00546 if (cpl_bivector_get_y_data(bivectors[i])[j] < locut)
00547 {
00548 cpl_bivector_get_y_data(bivectors[i])[j] = locut;
00549 }
00550 if (cpl_bivector_get_y_data(bivectors[i])[j] > hicut)
00551 {
00552 cpl_bivector_get_y_data(bivectors[i])[j] = hicut;
00553 }
00554 }
00555 }
00556 }
00557
00558
00559 temp = bivectors[0];
00560 bivectors[0] = bivectors[N-1];
00561 bivectors[N-1] = temp;
00562
00563 temps = options[0];
00564 options[0] = options[N-1];
00565 options[N-1] = temps;
00566
00567 pre = uves_sprintf(
00568 "set grid; set xlabel '%s'; set ylabel '%s';", xtitle, ytitle);
00569
00570 cpl_plot_bivectors(pre,
00571 (const char **)options,
00572 post,
00573 (const cpl_bivector **)bivectors, N);
00574
00575 RECOVER_FROM_ERROR(plotter);
00576 }
00577
00578 cleanup:
00579 cpl_free(pre);
00580 {
00581 int i;
00582 for (i = 0; i < N; i++)
00583 {
00584 cpl_free(options[i]);
00585 }
00586 }
00587 cpl_free(options);
00588 return;
00589 }
00590
00591
00607
00608 cpl_error_code
00609 uves_plot_table(const cpl_table *table, const char *colx, const char *coly,
00610 const char *format, ...)
00611 {
00612 va_list al;
00613
00614 char *pre = NULL;
00615 char *options = NULL;
00616 const char *post = "";
00617 cpl_table *thresholded = NULL;
00618
00619 assure( table != NULL, CPL_ERROR_NULL_INPUT, "Null table");
00620 assure( colx != NULL, CPL_ERROR_NULL_INPUT, "Null x column");
00621 assure( coly != NULL, CPL_ERROR_NULL_INPUT, "Null y column");
00622 assure( cpl_table_has_column(table, colx), CPL_ERROR_ILLEGAL_INPUT,
00623 "No such column: '%s'", colx);
00624 assure( cpl_table_has_column(table, coly), CPL_ERROR_ILLEGAL_INPUT,
00625 "No such column: '%s'", coly);
00626
00627 assure( cpl_table_get_column_type(table, colx) == CPL_TYPE_INT ||
00628 cpl_table_get_column_type(table, colx) == CPL_TYPE_FLOAT ||
00629 cpl_table_get_column_type(table, colx) == CPL_TYPE_DOUBLE,
00630 CPL_ERROR_TYPE_MISMATCH,
00631 "Column '%s' has type '%s'. Numerical type expected",
00632 colx,
00633 uves_tostring_cpl_type(cpl_table_get_column_type(table, colx)));
00634
00635 assure( cpl_table_get_column_type(table, coly) == CPL_TYPE_INT ||
00636 cpl_table_get_column_type(table, coly) == CPL_TYPE_FLOAT ||
00637 cpl_table_get_column_type(table, coly) == CPL_TYPE_DOUBLE,
00638 CPL_ERROR_TYPE_MISMATCH,
00639 "Column '%s' has type '%s'. Numerical type expected",
00640 coly,
00641 uves_tostring_cpl_type(cpl_table_get_column_type(table, coly)));
00642
00643 if (plotting_enabled)
00644 {
00645 const char *pre_format;
00646
00647
00648 va_start(al, format);
00649 vsnprintf(title, MAXTITLELENGTH - 1, format, al);
00650 va_end(al);
00651 title[MAXTITLELENGTH - 1] = '\0';
00652
00653 options = title_string(title, cpl_table_get_nrow(table));
00654
00655
00656 pre_format = "set grid; set xlabel '%s'; set ylabel '%s';";
00657 pre = cpl_calloc(strlen(pre_format) + strlen(colx) + strlen(coly) + 1,
00658 sizeof(char));
00659
00660 sprintf(pre, pre_format, colx, coly);
00661
00662
00663
00664 {
00665 double median, sigma, locut, hicut;
00666 int i;
00667
00668 median = cpl_table_get_column_median(table, coly);
00669 sigma = cpl_table_get_column_stdev(table, coly);
00670
00671 locut = median - 3*sigma;
00672 hicut = median + 3*sigma;
00673
00674
00675 thresholded = cpl_table_new(cpl_table_get_nrow(table));
00676 cpl_table_duplicate_column(thresholded, coly, table, coly);
00677 cpl_table_duplicate_column(thresholded, colx, table, colx);
00678
00679 for (i = 0; i < cpl_table_get_nrow(thresholded); i++)
00680 {
00681 double data = cpl_table_get(thresholded, coly, i, NULL);
00682
00683 if (data < locut && data > hicut)
00684 {
00685 cpl_table_set_invalid(thresholded, coly, i);
00686 }
00687 }
00688
00689 }
00690
00691 cpl_plot_column(pre,
00692 (strcmp(options, "t '%s'") == 0) ? "" : options,
00693 post,
00694 thresholded, colx, coly);
00695
00696 RECOVER_FROM_ERROR(plotter);
00697 }
00698
00699 cleanup:
00700 uves_free_table(&thresholded);
00701 cpl_free(pre);
00702 cpl_free(options);
00703
00704 return cpl_error_get_code();
00705 }
00706
00707
00708
00718
00719 static char *
00720 title_string(const char *plot_title, int npoints)
00721 {
00722
00723
00724
00725 const char *options = (npoints > 100) ?
00726 "w points pointsize 1" :
00727 "w linespoints pointsize 1";
00728
00729
00730 size_t length = strlen("t '' ") + strlen(plot_title) + strlen(options) + 1;
00731 char *result = cpl_calloc(length, sizeof(char));
00732
00733 snprintf(result, length, "t '%s' %s", plot_title, options);
00734
00735 return result;
00736 }
00737