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