irplib_plot.c

00001 /* $Id: irplib_plot.c,v 1.29 2007/05/22 08:33:53 jmlarsen Exp $
00002  *
00003  * This file is part of the irplib package
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: jmlarsen $
00023  * $Date: 2007/05/22 08:33:53 $
00024  * $Revision: 1.29 $
00025  * $Name: uves-3_3_1 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                    Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include <stdio.h>
00037 #include <unistd.h>
00038 #include <sys/types.h>
00039 #include <string.h>
00040 #include <stdlib.h>
00041 #include <assert.h>
00042 #include <float.h>
00043 
00044 /* Needed to get irplib_sprintf() */
00045 #include "irplib_utils.h"
00046 #include "irplib_plot.h"
00047 
00048 /*-----------------------------------------------------------------------------
00049                                    Define
00050  -----------------------------------------------------------------------------*/
00051 
00052 #define LINE_SIZE 80
00053 
00054 /*----------------------------------------------------------------------------*/
00065 /*----------------------------------------------------------------------------*/
00066 
00067 /*-----------------------------------------------------------------------------
00068                                    Type definition
00069  -----------------------------------------------------------------------------*/
00070 
00071 typedef struct _irplib_plot_ irplib_plot;
00072 
00073 struct _irplib_plot_ {
00074     /* File with data to be sent to plotting command's stdin */
00075     FILE * data;
00076 };
00077 
00078 /*-----------------------------------------------------------------------------
00079                         Private function prototypes
00080  -----------------------------------------------------------------------------*/
00081 
00082 static cpl_error_code irplib_mplot_puts(irplib_plot *, const char *);
00083 static cpl_error_code irplib_mplot_write(irplib_plot *, const char *, size_t);
00084 static irplib_plot * irplib_mplot_open(const char *);
00085 static irplib_plot * irplib_image_open(const char *);
00086 static cpl_error_code irplib_mplot_close(irplib_plot *, const char *);
00087 static const char * irplib_mplot_plotter(void);
00088 static const char * irplib_mplot_imager(void);
00089 
00090 /*-----------------------------------------------------------------------------
00091                         Private variables
00092  -----------------------------------------------------------------------------*/
00093 
00094 static const char *irplib_plot_filename = "irplib_plot.txt";
00095 
00096 /*-----------------------------------------------------------------------------
00097                                    Functions code
00098  -----------------------------------------------------------------------------*/
00101 /*----------------------------------------------------------------------------*/
00125 /*----------------------------------------------------------------------------*/
00126 cpl_error_code irplib_vector_plot_macro(const char          *   pre, 
00127                                         const char          *   options,
00128                                         const char          *   post, 
00129                                         const cpl_vector    *   vector,
00130                                         const char          *   file, 
00131                                         const unsigned          line) 
00132 {
00133     char           snumber[LINE_SIZE];
00134     const double * pvec      = cpl_vector_get_data(vector);
00135     const int      n         = cpl_vector_get_size(vector);
00136     cpl_error_code error     = CPL_ERROR_NONE;
00137     int            i;
00138     irplib_plot * plot;
00139 
00140 
00141     cpl_ensure_code(n > 0 , cpl_error_get_code());
00142 
00143     plot = irplib_mplot_open(pre);
00144 
00145     cpl_ensure_code(plot != NULL, cpl_error_get_code());
00146 
00147     error |= irplib_mplot_puts(plot, "plot '-' ");
00148 
00149     if (options != NULL) {
00150         error |= irplib_mplot_puts(plot, options);
00151     } else {
00152         char * myoptions = irplib_sprintf("t '%d-vector (%p) in "
00153                                                          "file %s line %u'",
00154                                                          n, (void*)vector, file,
00155                                                          line);
00156         assert(myoptions != NULL);
00157         error |= irplib_mplot_puts(plot, myoptions);
00158         cpl_free(myoptions);
00159     }
00160 
00161     error |= irplib_mplot_puts(plot, ";\n");
00162 
00163     for (i = 0; i < n; i++) {
00164         const int nlen = snprintf(snumber, LINE_SIZE, "%g\n", pvec[i]);
00165 
00166         assert(nlen > 0);
00167         error |= irplib_mplot_puts(plot, snumber);
00168         if (error) break;
00169     }
00170 
00171     error |= irplib_mplot_puts(plot, "e\n");
00172     error |= irplib_mplot_close(plot, post);
00173 
00174     return error ? cpl_error_get_code() : CPL_ERROR_NONE;
00175 }
00176 
00177 /*----------------------------------------------------------------------------*/
00203 /*----------------------------------------------------------------------------*/
00204 cpl_error_code irplib_bivector_plot_macro(const char          *   pre, 
00205                                           const char          *   options,
00206                                           const char          *   post,
00207                                           const cpl_bivector  *   bivector,
00208                                           const char          *   file, 
00209                                           const unsigned          line) 
00210 {
00211     char           snumber[LINE_SIZE];
00212     const int      n         = cpl_bivector_get_size(bivector);
00213     const double * pvecx     = cpl_bivector_get_x_data(bivector);
00214     const double * pvecy     = cpl_bivector_get_y_data(bivector);
00215     cpl_error_code error     = CPL_ERROR_NONE;
00216     irplib_plot  * plot;
00217     int            i;
00218 
00219 
00220     cpl_ensure_code(n > 0, cpl_error_get_code());
00221 
00222     plot = irplib_mplot_open(pre);
00223 
00224     cpl_ensure_code(plot != NULL, cpl_error_get_code());
00225 
00226     error |= irplib_mplot_puts(plot, "plot '-' ");
00227 
00228     if (options != NULL) {
00229         error |= irplib_mplot_puts(plot, options);
00230     } else {
00231         char * myoptions = irplib_sprintf("t '%d-bivector (%p) "
00232                                                          "in file %s line %u'",
00233                                                          n, (void*)bivector,
00234                                                          file, line);
00235 
00236         assert(myoptions != NULL);
00237         error |= irplib_mplot_puts(plot, myoptions);
00238         cpl_free(myoptions);
00239     }
00240 
00241     error |= irplib_mplot_puts(plot, ";\n");
00242 
00243     for (i = 0; i < n; i++) {
00244         const int nlen = snprintf(snumber, LINE_SIZE, "%g %g\n",
00245                                   pvecx[i], pvecy[i]);
00246 
00247         assert(nlen > 0);
00248         error |= irplib_mplot_puts(plot, snumber);
00249         if (error) break;
00250     }
00251 
00252     error |= irplib_mplot_puts(plot, "e\n");
00253     error |= irplib_mplot_close(plot, post);
00254 
00255     return error ? cpl_error_get_code() : CPL_ERROR_NONE;
00256 }
00257 
00258 /*----------------------------------------------------------------------------*/
00287 /*----------------------------------------------------------------------------*/
00288 cpl_error_code irplib_vectors_plot_macro(const char          *   pre, 
00289                                          const char          *   options,
00290                                          const char          *   post,
00291                                          const cpl_vector    **  vectors,
00292                                          int                     nvec)
00293 {
00294     double      *   pvecx ;
00295     double      *   pvecy ;
00296     int             vec_size = 0; /* Avoid uninit warning */
00297     char        **  names ;
00298     char            snumber[LINE_SIZE];
00299     char        *   sval;
00300     FILE        *   tmpfd ;
00301     irplib_plot *   plot ;
00302     int             i, j ;
00303     
00304     /* Check entries */
00305     cpl_ensure_code(vectors != NULL, CPL_ERROR_NULL_INPUT);
00306     cpl_ensure_code(nvec>=3, CPL_ERROR_NULL_INPUT);
00307     for (i=1 ; i<nvec ; i++) {
00308         cpl_ensure_code(vectors[i] != NULL, CPL_ERROR_NULL_INPUT);
00309         if (i==1) vec_size = cpl_vector_get_size(vectors[i]) ;
00310         else cpl_ensure_code(vec_size==cpl_vector_get_size(vectors[i]), 
00311                     CPL_ERROR_ILLEGAL_INPUT);
00312     }
00313     if (vectors[0] != NULL) {
00314         cpl_ensure_code(vec_size==cpl_vector_get_size(vectors[0]), 
00315                     CPL_ERROR_ILLEGAL_INPUT);
00316     }
00317 
00318     /* Get the X axis if passed */
00319     if (vectors[0] == NULL) pvecx = NULL ;
00320     else pvecx = cpl_vector_get_data(vectors[0]) ;
00321     
00322     /* Hold the files names */
00323     names = cpl_malloc((nvec-1)*sizeof(char*)) ;
00324     for (i=1 ; i<nvec ; i++)
00325     names[i-1] = irplib_sprintf("irplib_plot-%d", i) ;
00326     
00327     /* Open the plot */
00328     plot = irplib_mplot_open(pre);
00329 
00330     /* Loop on the signals to plot */
00331     for (i=1 ; i<nvec ; i++) {
00332         
00333         /* Get the current Y axis */
00334         pvecy = cpl_vector_get_data(vectors[i]) ;
00335 
00336         /* Open temporary file for output   */
00337     if ((tmpfd=fopen(names[i-1], "w"))==NULL) {
00338             irplib_mplot_close(plot, post);
00339             for (i=1 ; i<nvec ; i++) remove(names[i-1]) ; 
00340             for (i=1 ; i<nvec ; i++) cpl_free(names[i-1]) ; 
00341             cpl_free(names); 
00342             return CPL_ERROR_FILE_IO ;
00343         }
00344 
00345         /* Write data to this file  */
00346         for (j=0 ; j<vec_size ; j++) {
00347             int nlen;
00348 
00349             if (pvecx == NULL) {
00350                 nlen = snprintf(snumber, LINE_SIZE, "%g %g\n", (double)(j+1),
00351                                 pvecy[j]);
00352             } else {
00353                 nlen = snprintf(snumber, LINE_SIZE, "%g %g\n", pvecx[j],
00354                                 pvecy[j]);
00355             }
00356             assert(nlen > 0);
00357             if (fputs(snumber, tmpfd) < 0) break;
00358         }
00359         if (fclose(tmpfd) != 0) break;
00360         if (j != vec_size) break;
00361 
00362         /* Plot the file */
00363         if (i==1) {
00364             /* Plot the first signal */
00365             sval = irplib_sprintf("plot '%s' %s ;\n", names[i-1],
00366                                                  options);
00367         } else {
00368             sval = irplib_sprintf("replot '%s' t 'Vector %d' w "
00369                                                  "lines ;\n", names[i-1], i);
00370         }
00371         irplib_mplot_puts(plot, sval);
00372         cpl_free(sval);
00373     }
00374     irplib_mplot_close(plot, post);
00375     for (i=1 ; i<nvec ; i++) remove(names[i-1]) ; 
00376     for (i=1 ; i<nvec ; i++) cpl_free(names[i-1]) ; 
00377     cpl_free(names); 
00378     return cpl_error_get_code();
00379 }
00380 
00381 /*----------------------------------------------------------------------------*/
00412 /*----------------------------------------------------------------------------*/
00413 cpl_error_code irplib_bivectors_plot_macro(const char          *   pre, 
00414                        const char          **  options,
00415                        const char          *   post,
00416                        const cpl_bivector  **  bivectors,
00417                        int                     nbvec)
00418 {
00419     double      *   pvecx ;
00420     double      *   pvecy ;
00421     char        **  names ;
00422     char            snumber[LINE_SIZE];
00423     char        *   sval;
00424     FILE        *   tmpfd ;
00425     irplib_plot *   plot ;
00426     int             i, j ;
00427     
00428     /* Check entries */
00429     cpl_ensure_code(bivectors != NULL, CPL_ERROR_NULL_INPUT);
00430     cpl_ensure_code(options != NULL, CPL_ERROR_NULL_INPUT);
00431     cpl_ensure_code(nbvec>=1, CPL_ERROR_DATA_NOT_FOUND);
00432     for (i=0 ; i<nbvec ; i++) {
00433         cpl_ensure_code(bivectors[i] != NULL, CPL_ERROR_NULL_INPUT);
00434         cpl_ensure_code(  options[i] != NULL, CPL_ERROR_NULL_INPUT);
00435     }
00436 
00437     /* Hold the files names */
00438     names = cpl_malloc((nbvec)*sizeof(char*)) ;
00439     for (i=0 ; i<nbvec ; i++)
00440     names[i] = irplib_sprintf("irplib_plot-%d", i+1);
00441     
00442     /* Open the plot */
00443     plot = irplib_mplot_open(pre);
00444 
00445     /* Loop on the signals to plot */
00446     for (i=0 ; i<nbvec ; i++) {
00447     int vec_size;
00448         
00449         /* Get current vectors */
00450         pvecx = cpl_bivector_get_x_data(bivectors[i]) ;
00451         pvecy = cpl_bivector_get_y_data(bivectors[i]) ;
00452     vec_size = cpl_bivector_get_size(bivectors[i]) ;
00453 
00454         /* Open temporary file for output */
00455     if ((tmpfd=fopen(names[i], "w"))==NULL) {
00456             irplib_mplot_close(plot, post);
00457             for (i=0 ; i<nbvec ; i++) remove(names[i]) ;
00458             for (i=0 ; i<nbvec ; i++) cpl_free(names[i]) ;
00459             cpl_free(names);
00460             return CPL_ERROR_FILE_IO ;
00461         }
00462 
00463         /* Write data to this file  */
00464         for (j=0 ; j<vec_size ; j++) {
00465         const int nlen = snprintf(snumber, LINE_SIZE, "%g %g\n", pvecx[j],
00466                                       pvecy[j]);
00467             assert(nlen > 0);
00468             if (fputs(snumber, tmpfd) < 0) break;
00469         }
00470         if (fclose(tmpfd) != 0) break;
00471         if (j != vec_size) break;
00472 
00473     /* Plot the file using 'plot' the first time,
00474        otherwise use 'replot' */
00475     sval = irplib_sprintf("%splot '%s' %s ;\n", 
00476         i==0 ? "" : "re", names[i], options[i]);
00477     irplib_mplot_puts(plot, sval);
00478         cpl_free(sval);
00479     }
00480     irplib_mplot_close(plot, post);
00481     for (i=0 ; i<nbvec ; i++) remove(names[i]) ;
00482     for (i=0 ; i<nbvec ; i++) cpl_free(names[i]) ;
00483     cpl_free(names);
00484     return cpl_error_get_code();
00485 }
00486 
00487 /*----------------------------------------------------------------------------*/
00523 /*----------------------------------------------------------------------------*/
00524 cpl_error_code irplib_image_plot_macro(const char      *   pre, 
00525                                        const char      *   options,
00526                                        const char      *   post,
00527                                        const cpl_image *   image,
00528                                        const char      *   file, 
00529                                        const unsigned      line) 
00530 {
00531     char snumber[LINE_SIZE];
00532     const char    * irplib_plot_exe = irplib_mplot_imager();
00533     const int       nx = cpl_image_get_size_x(image);
00534     const int       ny = cpl_image_get_size_y(image);
00535     irplib_plot   * plot;
00536     cpl_image     * temp;
00537     const double  * pimage;
00538     unsigned char * raster = NULL;
00539     char          * dvi_options = (char *)options;
00540     char          * myoptions   = (char *)options;
00541     cpl_error_code  error = CPL_ERROR_NONE;
00542     int             i, j;
00543 
00544 
00545     cpl_ensure_code( nx > 0, cpl_error_get_code());
00546 
00547     plot = irplib_image_open(pre);
00548 
00549     cpl_ensure_code(plot != NULL, cpl_error_get_code());
00550 
00551     if (options == NULL || strlen(options) < 1) {
00552         dvi_options = irplib_sprintf("%dX%d-image-(%d) (%p) "
00553                                                     "in file %s line %u",
00554                                                     nx, ny, (int)
00555                                                     cpl_image_get_type(image),
00556                                                     (void*)image,
00557                                                     file, line);
00558         assert( dvi_options != NULL);
00559     }
00560 
00561     if (strstr(irplib_plot_exe, "gnuplot")) {
00562 
00563         if (cpl_image_get_type(image) == CPL_TYPE_DOUBLE) {
00564             temp = NULL;
00565             pimage = cpl_image_get_data_double(image);
00566         } else {
00567             temp = cpl_image_cast(image, CPL_TYPE_DOUBLE);
00568             pimage = cpl_image_get_data_double(temp);
00569         }
00570 
00571         error |= irplib_mplot_puts(plot, "splot '-' matrix ");
00572 
00573         if (myoptions == NULL || strlen(myoptions) < 1) {
00574 
00575             myoptions = irplib_sprintf("t '%s';",
00576                                                       dvi_options);
00577             assert( myoptions != NULL);
00578         }
00579         error |= irplib_mplot_puts(plot, myoptions);
00580         error |= irplib_mplot_puts(plot, ";\n");
00581 
00582         for (j = 0; j < ny; j++) {
00583             for (i = 0; i < nx; i++) {
00584                 const int nlen = snprintf(snumber, LINE_SIZE, "%g ",
00585                                           pimage[j*nx + i]);
00586 
00587                 assert(nlen > 0);
00588                 error |= irplib_mplot_puts(plot, snumber);
00589                 if (error) break;
00590             }
00591             error |= irplib_mplot_puts(plot, "\n");
00592             if (error) break;
00593         }
00594         error |= irplib_mplot_puts(plot, "e\n");
00595 
00596     } else {
00597         const size_t bsize = (size_t)(ny * nx); /* Octets in raster */
00598         int          nlen;
00599         const double tmin = cpl_image_get_min(image);
00600         double       tmax;
00601 
00602 
00603         /* Convert the image to one in the range [0; 256[ */
00604         if (cpl_image_get_type(image) == CPL_TYPE_DOUBLE)  {
00605             temp = cpl_image_subtract_scalar_create(image, tmin);
00606         } else {
00607             temp = cpl_image_cast(image, CPL_TYPE_DOUBLE);
00608             error |= cpl_image_subtract_scalar(temp, tmin);
00609         }
00610 
00611         tmax = cpl_image_get_max(temp);
00612 
00613         if (tmax > 0.0)
00614             error |= cpl_image_multiply_scalar(temp, 256.0*(1.0-DBL_EPSILON)
00615                                                /tmax);
00616 
00617         pimage = cpl_image_get_data_double(temp);
00618         assert(pimage != NULL);
00619 
00620         /* Create a PGM P5 header - with a maxval of 255 */
00621         nlen = snprintf(snumber, LINE_SIZE, "P5\n%d %d\n", nx, ny);
00622         assert(nlen > 0);
00623         error |= irplib_mplot_puts(plot, snumber);
00624 
00625         myoptions = irplib_sprintf("# True Value Range: "
00626                                                   "[%g;%g]\n",
00627                                                   tmin, tmin+tmax);
00628         assert( myoptions != NULL);
00629 
00630         error |= irplib_mplot_puts(plot, myoptions);
00631         cpl_free(myoptions);
00632 
00633         myoptions = irplib_sprintf("# %s\n255\n",
00634                                                   dvi_options);
00635 
00636         error |= irplib_mplot_puts(plot, myoptions);
00637 
00638         raster = (unsigned char *)cpl_malloc(bsize);
00639         for (j = 0; j < ny; j++) for (i = 0; i < nx; i++)
00640             raster[(ny-j-1)*nx + i] = (unsigned char) pimage[j*nx + i];
00641 
00642         error |= irplib_mplot_write(plot, (const char *) raster, bsize);
00643 
00644     }
00645 
00646 
00647     if (dvi_options != options) cpl_free(dvi_options);
00648     if (myoptions   != options) cpl_free(myoptions);
00649     cpl_free(raster);
00650     cpl_image_delete(temp);
00651 
00652     error |= irplib_mplot_close(plot, post);
00653 
00654     return error ? cpl_error_get_code() : CPL_ERROR_NONE;
00655 }
00656 
00657 /*----------------------------------------------------------------------------*/
00689 /*----------------------------------------------------------------------------*/
00690 cpl_error_code irplib_image_row_plot_macro(const char      *   pre,
00691                                            const char      *   options,
00692                                            const char      *   post,
00693                                            const cpl_image *   image,
00694                                            int                 firstrow, 
00695                                            int                 lastrow,
00696                                            int                 rowstep,
00697                                            const char      *   file,
00698                                            const unsigned      line) 
00699 {
00700     int nx, ny;
00701 
00702     cpl_ensure_code(image != NULL, CPL_ERROR_NULL_INPUT);
00703 
00704     nx = cpl_image_get_size_x(image);
00705     ny = cpl_image_get_size_y(image);
00706 
00707     cpl_ensure_code( nx > 0, CPL_ERROR_ILLEGAL_INPUT);
00708     cpl_ensure_code( ny > 0, CPL_ERROR_ILLEGAL_INPUT);
00709 
00710     cpl_ensure_code( rowstep > 0, CPL_ERROR_ILLEGAL_INPUT);
00711 
00712     cpl_ensure_code( firstrow > 0,    CPL_ERROR_ACCESS_OUT_OF_RANGE);
00713     cpl_ensure_code( firstrow <= lastrow, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00714     cpl_ensure_code( lastrow  <= ny,  CPL_ERROR_ACCESS_OUT_OF_RANGE);
00715    
00716     do {
00717 
00718         char snumber[LINE_SIZE];
00719         double * pimage;
00720         cpl_image * temp = NULL;
00721         char * myoptions = (char *)options;
00722         int i, j;
00723 
00724         irplib_plot * plot = irplib_mplot_open(pre);
00725 
00726         do {
00727             if (cpl_error_get_code()) break;
00728 
00729             if (irplib_mplot_puts(plot, "plot")) break;
00730             for (j = firstrow-1; j < lastrow; j += rowstep) {
00731                 if (j > firstrow-1 && irplib_mplot_puts(plot, ",")) break;
00732                 if (irplib_mplot_puts(plot, " '-' ")) break;
00733 
00734                 if (myoptions == NULL || strlen(myoptions) < 1) {
00735 
00736                     myoptions = (j == firstrow-1)
00737                         ? irplib_sprintf("t 'Row %d %dX%d-image-"
00738                                                  "(%d) (%p) in file %s "
00739                                                  "line %u'", j, nx, ny,
00740                                                  (int)cpl_image_get_type(image),
00741                                                  (void*)image, file, line)
00742                         : irplib_sprintf("t 'Row %d of the same "
00743                                                         "image'", j);
00744 
00745                         assert( myoptions != NULL);
00746 
00747                 }
00748                 if (irplib_mplot_puts(plot, myoptions    )) break;
00749                 if (myoptions != options) {
00750                     cpl_free(myoptions);
00751                     myoptions = NULL;
00752                 }
00753             }
00754             if (irplib_mplot_puts(plot, ";\n      ")) break;
00755 
00756             if (cpl_image_get_type(image) == CPL_TYPE_DOUBLE) {
00757                 pimage = cpl_image_get_data_double(image);
00758             } else {
00759                 temp = cpl_image_cast(image, CPL_TYPE_DOUBLE);
00760                 pimage = cpl_image_get_data_double(temp);
00761             }
00762 
00763             assert(pimage != NULL);
00764 
00765             for (j = firstrow-1; j < lastrow; j += rowstep) {
00766                 for (i = 0; i < nx; i++) {
00767                     const int nlen = snprintf(snumber, LINE_SIZE, "%g\n",
00768                                               pimage[j * nx + i]);
00769 
00770                     assert(nlen > 0);
00771                     if (irplib_mplot_puts(plot, snumber)) break;
00772                 }
00773                 if (i != nx) break;
00774                 if (irplib_mplot_puts(plot, "e\n")) break;
00775             }
00776             if (j != lastrow) break;
00777 
00778         } while (0);
00779 
00780         if (myoptions != options) cpl_free(myoptions);
00781         cpl_image_delete(temp);
00782 
00783         irplib_mplot_close(plot, post);
00784 
00785     } while (0);
00786 
00787     return cpl_error_get_code();
00788 }
00789 
00790 /*----------------------------------------------------------------------------*/
00822 /*----------------------------------------------------------------------------*/
00823 cpl_error_code irplib_image_col_plot_macro(const char      *   pre,
00824                                            const char      *   options,
00825                                            const char      *   post,
00826                                            const cpl_image *   image,
00827                                            int                 firstcol, 
00828                                            int                 lastcol,
00829                                            int                 colstep,
00830                                            const char      *   file,
00831                                            const unsigned      line) 
00832 {
00833     int nx, ny;
00834     cpl_ensure_code(image != NULL, CPL_ERROR_NULL_INPUT);
00835 
00836     nx = cpl_image_get_size_x(image);
00837     ny = cpl_image_get_size_y(image);
00838 
00839     cpl_ensure_code( nx > 0, CPL_ERROR_ILLEGAL_INPUT);
00840     cpl_ensure_code( ny > 0, CPL_ERROR_ILLEGAL_INPUT);
00841 
00842     cpl_ensure_code( colstep > 0, CPL_ERROR_ILLEGAL_INPUT);
00843 
00844     cpl_ensure_code( firstcol > 0,    CPL_ERROR_ACCESS_OUT_OF_RANGE);
00845     cpl_ensure_code( firstcol <= lastcol, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00846     cpl_ensure_code( lastcol  <= nx,  CPL_ERROR_ACCESS_OUT_OF_RANGE);
00847    
00848     do {
00849 
00850         char snumber[LINE_SIZE];
00851         double * pimage;
00852         cpl_image * temp = NULL;
00853         char * myoptions = (char *)options;
00854         int i, j;
00855 
00856         irplib_plot * plot = irplib_mplot_open(pre);
00857 
00858         do {
00859             if (cpl_error_get_code()) break;
00860 
00861             if (irplib_mplot_puts(plot, "plot")) break;
00862             for (i = firstcol-1; i < lastcol; i += colstep) {
00863                 if (i > firstcol-1 && irplib_mplot_puts(plot, ",")) break;
00864                 if (irplib_mplot_puts(plot, " '-' ")) break;
00865                 if (myoptions == NULL || strlen(myoptions) < 1) {
00866 
00867                     myoptions = (i == firstcol-1)
00868                         ? irplib_sprintf("t 'Column %d of a "
00869                                                  "%dX%d-image-(%d) (%p) "
00870                                                  "in file %s line %u'",
00871                                                  i, nx, ny,
00872                                                  (int)cpl_image_get_type(image),
00873                                                  (void*)image, file, line)
00874                         : irplib_sprintf("t 'Column %d of the "
00875                                                         "same image'", i);
00876                     assert( myoptions != NULL);
00877 
00878                 }
00879                 if (irplib_mplot_puts(plot, myoptions  )) break;
00880                 if (myoptions != options) {
00881                     cpl_free(myoptions);
00882                     myoptions = NULL;
00883                 }
00884             }
00885             if (irplib_mplot_puts(plot, ";\n      ")) break;
00886 
00887             if (cpl_image_get_type(image) == CPL_TYPE_DOUBLE) {
00888                 pimage = cpl_image_get_data_double(image);
00889             } else {
00890                 temp = cpl_image_cast(image, CPL_TYPE_DOUBLE);
00891                 pimage = cpl_image_get_data_double(temp);
00892             }
00893 
00894             for (i = firstcol-1; i < lastcol; i += colstep) {
00895                 for (j = 0; j < ny; j++) {
00896                     const int nlen = snprintf(snumber, LINE_SIZE, "%g\n",
00897                                               pimage[j * nx + i]);
00898 
00899                     assert(nlen > 0);
00900                     if (irplib_mplot_puts(plot, snumber)) break;
00901                 }
00902                 if (j != ny) break;
00903                 if (irplib_mplot_puts(plot, "e\n")) break;
00904             }
00905             if (i != lastcol) break;
00906 
00907         } while (0);
00908 
00909         if (myoptions != options) cpl_free(myoptions);
00910 
00911         cpl_image_delete(temp);
00912 
00913         irplib_mplot_close(plot, post);
00914 
00915     } while (0);
00916 
00917     return cpl_error_get_code();
00918 }
00919 
00920 /*----------------------------------------------------------------------------*/
00948 /*----------------------------------------------------------------------------*/
00949 cpl_error_code irplib_table_plot_macro(const char      *   pre, 
00950                                        const char      *   options,
00951                                        const char      *   post,
00952                                        const cpl_table *   tab,
00953                                        const char      *   xlab, 
00954                                        const char      *   ylab,
00955                                        const char      *   file, 
00956                                        const unsigned      line) 
00957 {
00958     int                 n;
00959     cpl_table       *   temp;
00960     cpl_bivector    *   bivect;
00961     cpl_vector      *   xvec;
00962     cpl_vector      *   yvec;
00963     cpl_type            type_x;
00964     cpl_type            type_y;
00965     int                 invalid_x;
00966     int                 invalid_y;
00967 
00968     /* Check input */
00969     cpl_ensure_code(tab, CPL_ERROR_NULL_INPUT);
00970     cpl_ensure_code(xlab, CPL_ERROR_NULL_INPUT);
00971     cpl_ensure_code(ylab, CPL_ERROR_NULL_INPUT);
00972     n = cpl_table_get_nrow(tab);
00973     cpl_ensure_code(n>0, CPL_ERROR_ILLEGAL_INPUT);
00974 
00975     cpl_ensure_code(cpl_table_has_column(tab, xlab), CPL_ERROR_DATA_NOT_FOUND);
00976     cpl_ensure_code(cpl_table_has_column(tab, ylab), CPL_ERROR_DATA_NOT_FOUND);
00977 
00978     type_x = cpl_table_get_column_type(tab, xlab);
00979     type_y = cpl_table_get_column_type(tab, ylab);
00980 
00981     cpl_ensure_code(type_x == CPL_TYPE_INT ||
00982             type_x == CPL_TYPE_FLOAT ||
00983             type_x == CPL_TYPE_DOUBLE, CPL_ERROR_INVALID_TYPE);
00984     cpl_ensure_code(type_y == CPL_TYPE_INT ||
00985             type_y == CPL_TYPE_FLOAT ||
00986             type_y == CPL_TYPE_DOUBLE, CPL_ERROR_INVALID_TYPE);
00987         
00988     invalid_x = cpl_table_count_invalid(tab, xlab);
00989     invalid_y = cpl_table_count_invalid(tab, ylab);
00990 
00991     if (invalid_x == n || invalid_y == n) return cpl_error_get_code();
00992 
00993     /* Cast columns to CPL_TYPE_DOUBLE and remove invalid entries */
00994     if (type_x != CPL_TYPE_DOUBLE || invalid_x > 0 ||
00995     type_y != CPL_TYPE_DOUBLE || invalid_y > 0)
00996     {
00997         temp = cpl_table_new(n);
00998         
00999         cpl_table_duplicate_column(temp, "X", (cpl_table*)tab, xlab);
01000         cpl_table_cast_column(temp, "X", "Xdouble", CPL_TYPE_DOUBLE);
01001         
01002         cpl_table_duplicate_column(temp, "Y", (cpl_table*)tab, ylab);
01003         cpl_table_cast_column(temp, "Y", "Ydouble", CPL_TYPE_DOUBLE);
01004         
01005         /* Remove rows with one or more invalid elements.
01006            No columns will be removed because each column
01007            contains at least one valid element. */
01008 
01009         cpl_table_erase_invalid(temp);
01010         
01011         xvec = cpl_vector_wrap(cpl_table_get_nrow(temp),
01012                    cpl_table_get_data_double(temp, "Xdouble"));
01013         
01014         yvec = cpl_vector_wrap(cpl_table_get_nrow(temp),
01015                    cpl_table_get_data_double(temp, "Ydouble"));
01016     }
01017     else
01018     {
01019         temp = NULL;
01020         
01021         xvec = cpl_vector_wrap(n, cpl_table_get_data_double((cpl_table*)tab,
01022                                                                 xlab));
01023         yvec = cpl_vector_wrap(n, cpl_table_get_data_double((cpl_table*)tab,
01024                                                                 ylab));
01025     }
01026     
01027     bivect = cpl_bivector_wrap_vectors(xvec, yvec);
01028     irplib_bivector_plot_macro(pre, options, post, bivect, file, line);
01029     
01030     cpl_bivector_unwrap_vectors(bivect);
01031     cpl_vector_unwrap(xvec);
01032     cpl_vector_unwrap(yvec);
01033     if (temp != NULL) cpl_table_delete(temp);
01034 
01035     return cpl_error_get_code();
01036 }
01037 
01040 /*----------------------------------------------------------------------------*/
01049 /*----------------------------------------------------------------------------*/
01050 static const char * irplib_mplot_plotter(void)
01051 {
01052     return getenv("IRPLIB_PLOTTER") ? getenv("IRPLIB_PLOTTER")
01053         : "gnuplot -persist";
01054 }
01055 
01056 /*----------------------------------------------------------------------------*/
01069 /*----------------------------------------------------------------------------*/
01070 static const char * irplib_mplot_imager(void)
01071 {
01072     return getenv("IRPLIB_IMAGER") ? getenv("IRPLIB_IMAGER")
01073         : irplib_mplot_plotter();
01074 }
01075 
01076 /*----------------------------------------------------------------------------*/
01115 /*----------------------------------------------------------------------------*/
01116 static irplib_plot * irplib_mplot_open(const char * options)
01117 {
01118     const char * irplib_plot_exe = irplib_mplot_plotter();
01119     irplib_plot * plot = NULL;
01120 
01121     if (irplib_plot_exe == NULL) return NULL;
01122 
01123     cpl_ensure(strstr(irplib_plot_exe, "gnuplot"), CPL_ERROR_UNSUPPORTED_MODE,
01124                NULL);
01125 
01126     plot = cpl_calloc(1, sizeof(irplib_plot));
01127 
01128     plot->data = fopen(irplib_plot_filename, "w");
01129 
01130     cpl_ensure(plot->data != NULL, CPL_ERROR_FILE_IO, NULL);
01131 
01132     if (irplib_mplot_puts(plot, options)) {
01133         (void)irplib_mplot_close(plot, "");
01134         cpl_ensure(0, cpl_error_get_code(), NULL);
01135     }
01136 
01137     return plot;
01138 }
01139 
01140 /*----------------------------------------------------------------------------*/
01167 /*----------------------------------------------------------------------------*/
01168 static irplib_plot * irplib_image_open(const char * options)
01169 {
01170     const char  * irplib_plot_exe = irplib_mplot_imager();
01171     irplib_plot * plot;
01172 
01173     if (irplib_plot_exe == NULL) return NULL;
01174 
01175     plot = cpl_calloc(1, sizeof(irplib_plot));
01176 
01177     plot->data = fopen(irplib_plot_filename, "w");
01178 
01179     cpl_ensure(plot->data != NULL, CPL_ERROR_FILE_IO, NULL);
01180 
01181     if (irplib_mplot_puts(plot, options)) {
01182         (void)irplib_mplot_close(plot, "");
01183         cpl_ensure(0, cpl_error_get_code(), NULL);
01184     }
01185 
01186     return plot;
01187 }
01188 
01189 /*----------------------------------------------------------------------------*/
01200 /*----------------------------------------------------------------------------*/
01201 static cpl_error_code irplib_mplot_close(irplib_plot * plot,
01202                                          const char  * options)
01203 {
01204     const char *irplib_plot_exe = irplib_mplot_plotter();
01205     const char *command;
01206     cpl_error_code error;
01207 
01208     if (irplib_plot_exe == NULL) return CPL_ERROR_NONE;
01209 
01210     cpl_ensure_code(plot != NULL, CPL_ERROR_NULL_INPUT);
01211 
01212     error = irplib_mplot_puts(plot, options);
01213 
01214     if (fclose(plot->data) != 0 && !error) error = CPL_ERROR_FILE_IO;
01215     cpl_free(plot);
01216 
01217     /* Note: The portability of this plotting module is limited by the
01218        portability of the following command (which is likely to be valid on
01219        any kind of UNIX platform). We use 'exec' to reduce the number of
01220        child processes created. */
01221     command = irplib_sprintf("exec <%s %s", 
01222                              irplib_plot_filename, irplib_plot_exe);
01223 
01224     if (system(command) != 0) error = CPL_ERROR_FILE_IO;
01225 
01226     cpl_free((void *)command); /* cast inserted to suppress warning about
01227                                   deallocating const objects which CPL does not
01228                                   support */
01229 
01230     remove(irplib_plot_filename);
01231 
01232     cpl_ensure_code(!error, error);
01233 
01234     return CPL_ERROR_NONE;
01235 }
01236 
01237 /*----------------------------------------------------------------------------*/
01249 /*----------------------------------------------------------------------------*/
01250 static cpl_error_code irplib_mplot_puts(irplib_plot * plot, const char * cmd)
01251 {
01252 
01253     cpl_ensure_code(plot != NULL, CPL_ERROR_NULL_INPUT);
01254 
01255     if (cmd == NULL || strlen(cmd) == 0) return CPL_ERROR_NONE;
01256 
01257     assert(plot->data != NULL);
01258 
01259     cpl_ensure_code(fputs(cmd, plot->data) >= 0, CPL_ERROR_FILE_IO);
01260 
01261     return CPL_ERROR_NONE;
01262 }
01263 
01264 /*----------------------------------------------------------------------------*/
01277 /*----------------------------------------------------------------------------*/
01278 static cpl_error_code irplib_mplot_write(irplib_plot     *   plot, 
01279                                          const char      *   buffer,
01280                                          size_t              length)
01281 {
01282     cpl_ensure_code(plot   != NULL, CPL_ERROR_NULL_INPUT);
01283     cpl_ensure_code(buffer != NULL, CPL_ERROR_NULL_INPUT);
01284     cpl_ensure_code(length > 0,     CPL_ERROR_ILLEGAL_INPUT);
01285 
01286     assert(plot->data != NULL);
01287 
01288     cpl_ensure_code(fwrite(buffer, 1, length, plot->data) == length,
01289                     CPL_ERROR_FILE_IO);
01290 
01291     return CPL_ERROR_NONE;
01292 }

Generated on Tue Jun 19 14:39:14 2007 for UVES Pipeline Reference Manual by  doxygen 1.4.6