irplib_plot.c

00001 /* $Id: irplib_plot.c,v 1.32 2008/02/13 15:30:25 llundin 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: llundin $
00023  * $Date: 2008/02/13 15:30:25 $
00024  * $Revision: 1.32 $
00025  * $Name: uves-3_9_0 $
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 #include "irplib_plot.h"
00045 
00046 /*-----------------------------------------------------------------------------
00047                                    Defines
00048  -----------------------------------------------------------------------------*/
00049 
00050 #ifndef IRPLIB_PLOT_TMPFILE
00051 #define IRPLIB_PLOT_TMPFILE "irplib_plot.txt"
00052 #endif
00053 
00054 #define LINE_SIZE 80
00055 
00056 /*----------------------------------------------------------------------------*/
00067 /*----------------------------------------------------------------------------*/
00068 
00069 /*-----------------------------------------------------------------------------
00070                                    Type definition
00071  -----------------------------------------------------------------------------*/
00072 
00073 typedef struct _irplib_plot_ irplib_plot;
00074 
00075 struct _irplib_plot_ {
00076     /* File with data to be sent to plotting command's stdin */
00077     FILE * data;
00078     /* Name of command capable of reading the plot on stdin */
00079     const char * exe;
00080     /* Name of temporary file for storing the plot commands */
00081     const char * tmp;
00082 };
00083 
00084 /*-----------------------------------------------------------------------------
00085                         Private function prototypes
00086  -----------------------------------------------------------------------------*/
00087 
00088 static cpl_error_code irplib_mplot_puts(irplib_plot *, const char *);
00089 static cpl_error_code irplib_mplot_write(irplib_plot *, const char *, size_t);
00090 static irplib_plot * irplib_mplot_open(const char *);
00091 static irplib_plot * irplib_image_open(const char *);
00092 static cpl_error_code irplib_mplot_close(irplib_plot *, const char *);
00093 static const char * irplib_mplot_plotter(void);
00094 static const char * irplib_mplot_imager(void);
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     const double * pvec      = cpl_vector_get_data_const(vector);
00134     const int      n         = cpl_vector_get_size(vector);
00135     cpl_error_code error     = CPL_ERROR_NONE;
00136     int            i;
00137     irplib_plot * plot;
00138 
00139 
00140     cpl_ensure_code(n > 0 , cpl_error_get_code());
00141 
00142     plot = irplib_mplot_open(pre);
00143 
00144     cpl_ensure_code(plot != NULL, cpl_error_get_code());
00145 
00146     error |= irplib_mplot_puts(plot, "plot '-' ");
00147 
00148     if (options != NULL) {
00149         error |= irplib_mplot_puts(plot, options);
00150     } else {
00151         char * myoptions = cpl_sprintf("t '%d-vector (%p) in "
00152                                                          "file %s line %u'",
00153                                                          n, (void*)vector, file,
00154                                                          line);
00155         assert(myoptions != NULL);
00156         error |= irplib_mplot_puts(plot, myoptions);
00157         cpl_free(myoptions);
00158     }
00159 
00160     error |= irplib_mplot_puts(plot, ";\n");
00161 
00162     for (i = 0; i < n; i++) {
00163         char * snumber = cpl_sprintf("%g\n", pvec[i]);
00164 
00165         error |= irplib_mplot_puts(plot, snumber);
00166         cpl_free(snumber);
00167         if (error) break;
00168     }
00169 
00170     error |= irplib_mplot_puts(plot, "e\n");
00171     error |= irplib_mplot_close(plot, post);
00172 
00173     return error ? cpl_error_get_code() : CPL_ERROR_NONE;
00174 }
00175 
00176 /*----------------------------------------------------------------------------*/
00202 /*----------------------------------------------------------------------------*/
00203 cpl_error_code irplib_bivector_plot_macro(const char          *   pre, 
00204                                           const char          *   options,
00205                                           const char          *   post,
00206                                           const cpl_bivector  *   bivector,
00207                                           const char          *   file, 
00208                                           const unsigned          line) 
00209 {
00210     const int      n         = cpl_bivector_get_size(bivector);
00211     const double * pvecx     = cpl_bivector_get_x_data_const(bivector);
00212     const double * pvecy     = cpl_bivector_get_y_data_const(bivector);
00213     cpl_error_code error     = CPL_ERROR_NONE;
00214     irplib_plot  * plot;
00215     int            i;
00216 
00217 
00218     cpl_ensure_code(n > 0, cpl_error_get_code());
00219 
00220     plot = irplib_mplot_open(pre);
00221 
00222     cpl_ensure_code(plot != NULL, cpl_error_get_code());
00223 
00224     error |= irplib_mplot_puts(plot, "plot '-' ");
00225 
00226     if (options != NULL) {
00227         error |= irplib_mplot_puts(plot, options);
00228     } else {
00229         char * myoptions = cpl_sprintf("t '%d-bivector (%p) "
00230                                                          "in file %s line %u'",
00231                                                          n, (void*)bivector,
00232                                                          file, line);
00233 
00234         assert(myoptions != NULL);
00235         error |= irplib_mplot_puts(plot, myoptions);
00236         cpl_free(myoptions);
00237     }
00238 
00239     error |= irplib_mplot_puts(plot, ";\n");
00240 
00241     for (i = 0; i < n; i++) {
00242         char * snumber = cpl_sprintf("%g %g\n", pvecx[i], pvecy[i]);
00243 
00244         error |= irplib_mplot_puts(plot, snumber);
00245         cpl_free(snumber);
00246         if (error) break;
00247     }
00248 
00249     error |= irplib_mplot_puts(plot, "e\n");
00250     error |= irplib_mplot_close(plot, post);
00251 
00252     return error ? cpl_error_get_code() : CPL_ERROR_NONE;
00253 }
00254 
00255 /*----------------------------------------------------------------------------*/
00284 /*----------------------------------------------------------------------------*/
00285 cpl_error_code irplib_vectors_plot_macro(const char          *   pre, 
00286                                          const char          *   options,
00287                                          const char          *   post,
00288                                          const cpl_vector    **  vectors,
00289                                          int                     nvec)
00290 {
00291     const double    *   pvecx ;
00292     const double    *   pvecy ;
00293     int                 vec_size = 0; /* Avoid uninit warning */
00294     char            **  names ;
00295     char            *   sval;
00296     FILE            *   tmpfd ;
00297     irplib_plot     *   plot ;
00298     int                 i, j ;
00299     
00300     /* Check entries */
00301     cpl_ensure_code(vectors != NULL, CPL_ERROR_NULL_INPUT);
00302     cpl_ensure_code(nvec>=3, CPL_ERROR_NULL_INPUT);
00303     for (i=1 ; i<nvec ; i++) {
00304         cpl_ensure_code(vectors[i] != NULL, CPL_ERROR_NULL_INPUT);
00305         if (i==1) vec_size = cpl_vector_get_size(vectors[i]) ;
00306         else cpl_ensure_code(vec_size==cpl_vector_get_size(vectors[i]), 
00307                     CPL_ERROR_ILLEGAL_INPUT);
00308     }
00309     if (vectors[0] != NULL) {
00310         cpl_ensure_code(vec_size==cpl_vector_get_size(vectors[0]), 
00311                     CPL_ERROR_ILLEGAL_INPUT);
00312     }
00313 
00314     /* Get the X axis if passed */
00315     if (vectors[0] == NULL) pvecx = NULL ;
00316     else pvecx = cpl_vector_get_data_const(vectors[0]) ;
00317     
00318     /* Hold the files names */
00319     names = cpl_malloc((nvec-1)*sizeof(char*)) ;
00320     for (i=1 ; i<nvec ; i++)
00321     names[i-1] = cpl_sprintf("irplib_plot-%d", i) ;
00322     
00323     /* Open the plot */
00324     plot = irplib_mplot_open(pre);
00325 
00326     /* Loop on the signals to plot */
00327     for (i=1 ; i<nvec ; i++) {
00328         
00329         /* Get the current Y axis */
00330         pvecy = cpl_vector_get_data_const(vectors[i]) ;
00331 
00332         /* Open temporary file for output   */
00333     if ((tmpfd=fopen(names[i-1], "w"))==NULL) {
00334             irplib_mplot_close(plot, post);
00335             for (i=1 ; i<nvec ; i++) remove(names[i-1]) ; 
00336             for (i=1 ; i<nvec ; i++) cpl_free(names[i-1]) ; 
00337             cpl_free(names); 
00338             return CPL_ERROR_FILE_IO ;
00339         }
00340 
00341         /* Write data to this file  */
00342         for (j=0 ; j<vec_size ; j++) {
00343             char * snumber = cpl_sprintf("%g %g\n",
00344                                          pvecx == NULL ? (double)(j+1)
00345                                          : pvecx[j], pvecy[j]);
00346             const int nstat = fputs(snumber, tmpfd);
00347 
00348             cpl_free(snumber);
00349             if (nstat < 0) break;
00350 
00351         }
00352         if (fclose(tmpfd) != 0) break;
00353         if (j != vec_size) break;
00354 
00355         /* Plot the file */
00356         if (i==1) {
00357             /* Plot the first signal */
00358             sval = cpl_sprintf("plot '%s' %s ;\n", names[i-1],
00359                                                  options);
00360         } else {
00361             sval = cpl_sprintf("replot '%s' t 'Vector %d' w "
00362                                                  "lines ;\n", names[i-1], i);
00363         }
00364         irplib_mplot_puts(plot, sval);
00365         cpl_free(sval);
00366     }
00367     irplib_mplot_close(plot, post);
00368     for (i=1 ; i<nvec ; i++) remove(names[i-1]) ; 
00369     for (i=1 ; i<nvec ; i++) cpl_free(names[i-1]) ; 
00370     cpl_free(names); 
00371     return cpl_error_get_code();
00372 }
00373 
00374 /*----------------------------------------------------------------------------*/
00405 /*----------------------------------------------------------------------------*/
00406 cpl_error_code irplib_bivectors_plot_macro(const char          *   pre, 
00407                        const char          **  options,
00408                        const char          *   post,
00409                        const cpl_bivector  **  bivectors,
00410                        int                     nbvec)
00411 {
00412     const double    *   pvecx ;
00413     const double    *   pvecy ;
00414     char            **  names ;
00415     char            *   sval;
00416     FILE            *   tmpfd ;
00417     irplib_plot     *   plot ;
00418     int                 i, j ;
00419     
00420     /* Check entries */
00421     cpl_ensure_code(bivectors != NULL, CPL_ERROR_NULL_INPUT);
00422     cpl_ensure_code(options != NULL, CPL_ERROR_NULL_INPUT);
00423     cpl_ensure_code(nbvec>=1, CPL_ERROR_DATA_NOT_FOUND);
00424     for (i=0 ; i<nbvec ; i++) {
00425         cpl_ensure_code(bivectors[i] != NULL, CPL_ERROR_NULL_INPUT);
00426         cpl_ensure_code(  options[i] != NULL, CPL_ERROR_NULL_INPUT);
00427     }
00428 
00429     /* Hold the files names */
00430     names = cpl_malloc((nbvec)*sizeof(char*)) ;
00431     for (i=0 ; i<nbvec ; i++)
00432     names[i] = cpl_sprintf("irplib_plot-%d", i+1);
00433     
00434     /* Open the plot */
00435     plot = irplib_mplot_open(pre);
00436 
00437     /* Loop on the signals to plot */
00438     for (i=0 ; i<nbvec ; i++) {
00439         int vec_size;
00440         
00441         /* Get current vectors */
00442         pvecx = cpl_bivector_get_x_data_const(bivectors[i]) ;
00443         pvecy = cpl_bivector_get_y_data_const(bivectors[i]) ;
00444 
00445         vec_size = cpl_bivector_get_size(bivectors[i]) ;
00446 
00447         /* Open temporary file for output */
00448         if ((tmpfd=fopen(names[i], "w"))==NULL) {
00449             irplib_mplot_close(plot, post);
00450             for (i=0 ; i<nbvec ; i++) remove(names[i]) ;
00451             for (i=0 ; i<nbvec ; i++) cpl_free(names[i]) ;
00452             cpl_free(names);
00453             return CPL_ERROR_FILE_IO ;
00454         }
00455 
00456         /* Write data to this file  */
00457         for (j=0 ; j<vec_size ; j++) {
00458             char * snumber = cpl_sprintf("%g %g\n", pvecx[j], pvecy[j]);
00459             const int nstat = fputs(snumber, tmpfd);
00460 
00461             cpl_free(snumber);
00462             if (nstat < 0) break;
00463         }
00464         if (fclose(tmpfd) != 0) break;
00465         if (j != vec_size) break;
00466 
00467     /* Plot the file using 'plot' the first time,
00468        otherwise use 'replot' */
00469     sval = cpl_sprintf("%splot '%s' %s ;\n", 
00470         i==0 ? "" : "re", names[i], options[i]);
00471     irplib_mplot_puts(plot, sval);
00472         cpl_free(sval);
00473     }
00474     irplib_mplot_close(plot, post);
00475     for (i=0 ; i<nbvec ; i++) remove(names[i]) ;
00476     for (i=0 ; i<nbvec ; i++) cpl_free(names[i]) ;
00477     cpl_free(names);
00478     return cpl_error_get_code();
00479 }
00480 
00481 /*----------------------------------------------------------------------------*/
00517 /*----------------------------------------------------------------------------*/
00518 cpl_error_code irplib_image_plot_macro(const char      *   pre, 
00519                                        const char      *   options,
00520                                        const char      *   post,
00521                                        const cpl_image *   image,
00522                                        const char      *   file, 
00523                                        const unsigned      line) 
00524 {
00525     const int       nx = cpl_image_get_size_x(image);
00526     const int       ny = cpl_image_get_size_y(image);
00527     irplib_plot   * plot;
00528     cpl_image     * temp;
00529     const double  * pimage;
00530     unsigned char * raster = NULL;
00531     char          * dvi_options = (char *)options;
00532     char          * myoptions   = (char *)options;
00533     cpl_error_code  error = CPL_ERROR_NONE;
00534     int             i, j;
00535 
00536 
00537     cpl_ensure_code( nx > 0, cpl_error_get_code());
00538 
00539     plot = irplib_image_open(pre);
00540 
00541     cpl_ensure_code(plot      != NULL, cpl_error_get_code());
00542 
00543     if (options == NULL || strlen(options) < 1) {
00544         dvi_options = cpl_sprintf("%dX%d-image-(%d) (%p) "
00545                                                     "in file %s line %u",
00546                                                     nx, ny, (int)
00547                                                     cpl_image_get_type(image),
00548                                                     (void*)image,
00549                                                     file, line);
00550         assert( dvi_options != NULL);
00551     }
00552 
00553     assert(plot->exe != NULL);
00554     if (strstr(plot->exe, "gnuplot")) {
00555 
00556         if (cpl_image_get_type(image) == CPL_TYPE_DOUBLE) {
00557             temp = NULL;
00558             pimage = cpl_image_get_data_double_const(image);
00559         } else {
00560             temp = cpl_image_cast(image, CPL_TYPE_DOUBLE);
00561             pimage = cpl_image_get_data_double(temp);
00562         }
00563 
00564         error |= irplib_mplot_puts(plot, "splot '-' matrix ");
00565 
00566         if (myoptions == NULL || strlen(myoptions) < 1) {
00567 
00568             myoptions = cpl_sprintf("t '%s';",
00569                                                       dvi_options);
00570             assert( myoptions != NULL);
00571         }
00572         error |= irplib_mplot_puts(plot, myoptions);
00573         error |= irplib_mplot_puts(plot, ";\n");
00574 
00575         for (j = 0; j < ny; j++) {
00576             for (i = 0; i < nx; i++) {
00577                 char * snumber = cpl_sprintf("%g ", pimage[j*nx + i]);
00578 
00579                 error |= irplib_mplot_puts(plot, snumber);
00580                 cpl_free(snumber);
00581                 if (error) break;
00582             }
00583             error |= irplib_mplot_puts(plot, "\n");
00584             if (error) break;
00585         }
00586         error |= irplib_mplot_puts(plot, "e\n");
00587 
00588     } else {
00589         const size_t bsize = (size_t)(ny * nx); /* Octets in raster */
00590         const double tmin = cpl_image_get_min(image);
00591         double       tmax;
00592 
00593 
00594         /* Convert the image to one in the range [0; 256[ */
00595         if (cpl_image_get_type(image) == CPL_TYPE_DOUBLE)  {
00596             temp = cpl_image_subtract_scalar_create(image, tmin);
00597         } else {
00598             temp = cpl_image_cast(image, CPL_TYPE_DOUBLE);
00599             error |= cpl_image_subtract_scalar(temp, tmin);
00600         }
00601 
00602         tmax = cpl_image_get_max(temp);
00603 
00604         if (tmax > 0.0)
00605             error |= cpl_image_multiply_scalar(temp, 256.0*(1.0-DBL_EPSILON)
00606                                                /tmax);
00607 
00608         pimage = cpl_image_get_data_double(temp);
00609         assert(pimage != NULL);
00610 
00611         /* Create a PGM P5 header - with a maxval of 255 */
00612         myoptions = cpl_sprintf("P5\n%d %d\n", nx, ny);
00613         error |= irplib_mplot_puts(plot, myoptions);
00614         cpl_free(myoptions);
00615 
00616         myoptions = cpl_sprintf("# True Value Range: [%g;%g]\n",
00617                                    tmin, tmin+tmax);
00618         assert( myoptions != NULL);
00619 
00620         error |= irplib_mplot_puts(plot, myoptions);
00621         cpl_free(myoptions);
00622 
00623         myoptions = cpl_sprintf("# %s\n255\n", dvi_options);
00624 
00625         error |= irplib_mplot_puts(plot, myoptions);
00626 
00627         raster = (unsigned char *)cpl_malloc(bsize);
00628         for (j = 0; j < ny; j++) for (i = 0; i < nx; i++)
00629             raster[(ny-j-1)*nx + i] = (unsigned char) pimage[j*nx + i];
00630 
00631         error |= irplib_mplot_write(plot, (const char *) raster, bsize);
00632 
00633     }
00634 
00635 
00636     if (dvi_options != options) cpl_free(dvi_options);
00637     if (myoptions   != options) cpl_free(myoptions);
00638     cpl_free(raster);
00639     cpl_image_delete(temp);
00640 
00641     error |= irplib_mplot_close(plot, post);
00642 
00643     return error ? cpl_error_get_code() : CPL_ERROR_NONE;
00644 }
00645 
00646 /*----------------------------------------------------------------------------*/
00678 /*----------------------------------------------------------------------------*/
00679 cpl_error_code irplib_image_row_plot_macro(const char      *   pre,
00680                                            const char      *   options,
00681                                            const char      *   post,
00682                                            const cpl_image *   image,
00683                                            int                 firstrow, 
00684                                            int                 lastrow,
00685                                            int                 rowstep,
00686                                            const char      *   file,
00687                                            const unsigned      line) 
00688 {
00689     int nx, ny;
00690 
00691     cpl_ensure_code(image != NULL, CPL_ERROR_NULL_INPUT);
00692 
00693     nx = cpl_image_get_size_x(image);
00694     ny = cpl_image_get_size_y(image);
00695 
00696     cpl_ensure_code( nx > 0, CPL_ERROR_ILLEGAL_INPUT);
00697     cpl_ensure_code( ny > 0, CPL_ERROR_ILLEGAL_INPUT);
00698 
00699     cpl_ensure_code( rowstep > 0, CPL_ERROR_ILLEGAL_INPUT);
00700 
00701     cpl_ensure_code( firstrow > 0,    CPL_ERROR_ACCESS_OUT_OF_RANGE);
00702     cpl_ensure_code( firstrow <= lastrow, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00703     cpl_ensure_code( lastrow  <= ny,  CPL_ERROR_ACCESS_OUT_OF_RANGE);
00704    
00705     do {
00706 
00707         const double * pimage;
00708         cpl_image * temp = NULL;
00709         char * myoptions = (char *)options;
00710         int i, j;
00711 
00712         irplib_plot * plot = irplib_mplot_open(pre);
00713 
00714         do {
00715             if (cpl_error_get_code()) break;
00716 
00717             if (irplib_mplot_puts(plot, "plot")) break;
00718             for (j = firstrow-1; j < lastrow; j += rowstep) {
00719                 if (j > firstrow-1 && irplib_mplot_puts(plot, ",")) break;
00720                 if (irplib_mplot_puts(plot, " '-' ")) break;
00721 
00722                 if (myoptions == NULL || strlen(myoptions) < 1) {
00723 
00724                     myoptions = (j == firstrow-1)
00725                         ? cpl_sprintf("t 'Row %d %dX%d-image-"
00726                                                  "(%d) (%p) in file %s "
00727                                                  "line %u'", j, nx, ny,
00728                                                  (int)cpl_image_get_type(image),
00729                                                  (void*)image, file, line)
00730                         : cpl_sprintf("t 'Row %d of the same "
00731                                                         "image'", j);
00732 
00733                         assert( myoptions != NULL);
00734 
00735                 }
00736                 if (irplib_mplot_puts(plot, myoptions    )) break;
00737                 if (myoptions != options) {
00738                     cpl_free(myoptions);
00739                     myoptions = NULL;
00740                 }
00741             }
00742             if (irplib_mplot_puts(plot, ";\n      ")) break;
00743 
00744             if (cpl_image_get_type(image) == CPL_TYPE_DOUBLE) {
00745                 pimage = cpl_image_get_data_double_const(image);
00746             } else {
00747                 temp = cpl_image_cast(image, CPL_TYPE_DOUBLE);
00748                 pimage = cpl_image_get_data_double(temp);
00749             }
00750 
00751             assert(pimage != NULL);
00752 
00753             for (j = firstrow-1; j < lastrow; j += rowstep) {
00754                 for (i = 0; i < nx; i++) {
00755                     char * snumber = cpl_sprintf("%g\n", pimage[j * nx + i]);
00756                     const int nstat = irplib_mplot_puts(plot, snumber);
00757 
00758                     cpl_free(snumber);
00759                     if (nstat) break;
00760                 }
00761                 if (i != nx) break;
00762                 if (irplib_mplot_puts(plot, "e\n")) break;
00763             }
00764             if (j != lastrow) break;
00765 
00766         } while (0);
00767 
00768         if (myoptions != options) cpl_free(myoptions);
00769         cpl_image_delete(temp);
00770 
00771         irplib_mplot_close(plot, post);
00772 
00773     } while (0);
00774 
00775     return cpl_error_get_code();
00776 }
00777 
00778 /*----------------------------------------------------------------------------*/
00810 /*----------------------------------------------------------------------------*/
00811 cpl_error_code irplib_image_col_plot_macro(const char      *   pre,
00812                                            const char      *   options,
00813                                            const char      *   post,
00814                                            const cpl_image *   image,
00815                                            int                 firstcol, 
00816                                            int                 lastcol,
00817                                            int                 colstep,
00818                                            const char      *   file,
00819                                            const unsigned      line) 
00820 {
00821     int nx, ny;
00822     cpl_ensure_code(image != NULL, CPL_ERROR_NULL_INPUT);
00823 
00824     nx = cpl_image_get_size_x(image);
00825     ny = cpl_image_get_size_y(image);
00826 
00827     cpl_ensure_code( nx > 0, CPL_ERROR_ILLEGAL_INPUT);
00828     cpl_ensure_code( ny > 0, CPL_ERROR_ILLEGAL_INPUT);
00829 
00830     cpl_ensure_code( colstep > 0, CPL_ERROR_ILLEGAL_INPUT);
00831 
00832     cpl_ensure_code( firstcol > 0,    CPL_ERROR_ACCESS_OUT_OF_RANGE);
00833     cpl_ensure_code( firstcol <= lastcol, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00834     cpl_ensure_code( lastcol  <= nx,  CPL_ERROR_ACCESS_OUT_OF_RANGE);
00835    
00836     do {
00837 
00838         const double * pimage;
00839         cpl_image * temp = NULL;
00840         char * myoptions = (char *)options;
00841         int i, j;
00842 
00843         irplib_plot * plot = irplib_mplot_open(pre);
00844 
00845         do {
00846             if (cpl_error_get_code()) break;
00847 
00848             if (irplib_mplot_puts(plot, "plot")) break;
00849             for (i = firstcol-1; i < lastcol; i += colstep) {
00850                 if (i > firstcol-1 && irplib_mplot_puts(plot, ",")) break;
00851                 if (irplib_mplot_puts(plot, " '-' ")) break;
00852                 if (myoptions == NULL || strlen(myoptions) < 1) {
00853 
00854                     myoptions = (i == firstcol-1)
00855                         ? cpl_sprintf("t 'Column %d of a "
00856                                                  "%dX%d-image-(%d) (%p) "
00857                                                  "in file %s line %u'",
00858                                                  i, nx, ny,
00859                                                  (int)cpl_image_get_type(image),
00860                                                  (void*)image, file, line)
00861                         : cpl_sprintf("t 'Column %d of the "
00862                                                         "same image'", i);
00863                     assert( myoptions != NULL);
00864 
00865                 }
00866                 if (irplib_mplot_puts(plot, myoptions  )) break;
00867                 if (myoptions != options) {
00868                     cpl_free(myoptions);
00869                     myoptions = NULL;
00870                 }
00871             }
00872             if (irplib_mplot_puts(plot, ";\n      ")) break;
00873 
00874             if (cpl_image_get_type(image) == CPL_TYPE_DOUBLE) {
00875                 pimage = cpl_image_get_data_double_const(image);
00876             } else {
00877                 temp = cpl_image_cast(image, CPL_TYPE_DOUBLE);
00878                 pimage = cpl_image_get_data_double_const(temp);
00879             }
00880 
00881             for (i = firstcol-1; i < lastcol; i += colstep) {
00882                 for (j = 0; j < ny; j++) {
00883                     char * snumber = cpl_sprintf("%g\n", pimage[j * nx + i]);
00884                     const int nstat = irplib_mplot_puts(plot, snumber);
00885 
00886                     cpl_free(snumber);
00887                     if (nstat) break;
00888                 }
00889                 if (j != ny) break;
00890                 if (irplib_mplot_puts(plot, "e\n")) break;
00891             }
00892             if (i != lastcol) break;
00893 
00894         } while (0);
00895 
00896         if (myoptions != options) cpl_free(myoptions);
00897 
00898         cpl_image_delete(temp);
00899 
00900         irplib_mplot_close(plot, post);
00901 
00902     } while (0);
00903 
00904     return cpl_error_get_code();
00905 }
00906 
00907 /*----------------------------------------------------------------------------*/
00935 /*----------------------------------------------------------------------------*/
00936 cpl_error_code irplib_table_plot_macro(const char      *   pre, 
00937                                        const char      *   options,
00938                                        const char      *   post,
00939                                        const cpl_table *   tab,
00940                                        const char      *   xlab, 
00941                                        const char      *   ylab,
00942                                        const char      *   file, 
00943                                        const unsigned      line) 
00944 {
00945     int                 n;
00946     cpl_table       *   temp;
00947     cpl_bivector    *   bivect;
00948     cpl_vector      *   xvec;
00949     cpl_vector      *   yvec;
00950     cpl_type            type_x;
00951     cpl_type            type_y;
00952     int                 invalid_x;
00953     int                 invalid_y;
00954 
00955     /* Check input */
00956     cpl_ensure_code(tab, CPL_ERROR_NULL_INPUT);
00957     cpl_ensure_code(xlab, CPL_ERROR_NULL_INPUT);
00958     cpl_ensure_code(ylab, CPL_ERROR_NULL_INPUT);
00959     n = cpl_table_get_nrow(tab);
00960     cpl_ensure_code(n>0, CPL_ERROR_ILLEGAL_INPUT);
00961 
00962     cpl_ensure_code(cpl_table_has_column(tab, xlab), CPL_ERROR_DATA_NOT_FOUND);
00963     cpl_ensure_code(cpl_table_has_column(tab, ylab), CPL_ERROR_DATA_NOT_FOUND);
00964 
00965     type_x = cpl_table_get_column_type(tab, xlab);
00966     type_y = cpl_table_get_column_type(tab, ylab);
00967 
00968     cpl_ensure_code(type_x == CPL_TYPE_INT ||
00969             type_x == CPL_TYPE_FLOAT ||
00970             type_x == CPL_TYPE_DOUBLE, CPL_ERROR_INVALID_TYPE);
00971     cpl_ensure_code(type_y == CPL_TYPE_INT ||
00972             type_y == CPL_TYPE_FLOAT ||
00973             type_y == CPL_TYPE_DOUBLE, CPL_ERROR_INVALID_TYPE);
00974         
00975     invalid_x = cpl_table_count_invalid(tab, xlab);
00976     invalid_y = cpl_table_count_invalid(tab, ylab);
00977 
00978     if (invalid_x == n || invalid_y == n) return cpl_error_get_code();
00979 
00980     /* Cast columns to CPL_TYPE_DOUBLE and remove invalid entries */
00981     if (type_x != CPL_TYPE_DOUBLE || invalid_x > 0 ||
00982     type_y != CPL_TYPE_DOUBLE || invalid_y > 0)
00983     {
00984         temp = cpl_table_new(n);
00985         
00986         cpl_table_duplicate_column(temp, "X", (cpl_table*)tab, xlab);
00987         cpl_table_cast_column(temp, "X", "Xdouble", CPL_TYPE_DOUBLE);
00988         
00989         cpl_table_duplicate_column(temp, "Y", (cpl_table*)tab, ylab);
00990         cpl_table_cast_column(temp, "Y", "Ydouble", CPL_TYPE_DOUBLE);
00991         
00992         /* Remove rows with one or more invalid elements.
00993            No columns will be removed because each column
00994            contains at least one valid element. */
00995 
00996         cpl_table_erase_invalid(temp);
00997         
00998         xvec = cpl_vector_wrap(cpl_table_get_nrow(temp),
00999                    cpl_table_get_data_double(temp, "Xdouble"));
01000         
01001         yvec = cpl_vector_wrap(cpl_table_get_nrow(temp),
01002                    cpl_table_get_data_double(temp, "Ydouble"));
01003     }
01004     else
01005     {
01006         temp = NULL;
01007         
01008         xvec = cpl_vector_wrap(n, cpl_table_get_data_double((cpl_table*)tab,
01009                                                                 xlab));
01010         yvec = cpl_vector_wrap(n, cpl_table_get_data_double((cpl_table*)tab,
01011                                                                 ylab));
01012     }
01013     
01014     bivect = cpl_bivector_wrap_vectors(xvec, yvec);
01015     irplib_bivector_plot_macro(pre, options, post, bivect, file, line);
01016     
01017     cpl_bivector_unwrap_vectors(bivect);
01018     cpl_vector_unwrap(xvec);
01019     cpl_vector_unwrap(yvec);
01020     if (temp != NULL) cpl_table_delete(temp);
01021 
01022     return cpl_error_get_code();
01023 }
01024 
01027 /*----------------------------------------------------------------------------*/
01036 /*----------------------------------------------------------------------------*/
01037 static const char * irplib_mplot_plotter(void)
01038 {
01039     return getenv("IRPLIB_PLOTTER") ? getenv("IRPLIB_PLOTTER")
01040         : "gnuplot -persist";
01041 }
01042 
01043 /*----------------------------------------------------------------------------*/
01056 /*----------------------------------------------------------------------------*/
01057 static const char * irplib_mplot_imager(void)
01058 {
01059     return getenv("IRPLIB_IMAGER") ? getenv("IRPLIB_IMAGER")
01060         : irplib_mplot_plotter();
01061 }
01062 
01063 /*----------------------------------------------------------------------------*/
01102 /*----------------------------------------------------------------------------*/
01103 static irplib_plot * irplib_mplot_open(const char * options)
01104 {
01105     irplib_plot * plot;
01106     const char * exe = irplib_mplot_plotter();
01107     const char * tmp = IRPLIB_PLOT_TMPFILE;
01108     FILE * data;
01109 
01110 
01111     cpl_ensure(exe != NULL, CPL_ERROR_NULL_INPUT, NULL);
01112     cpl_ensure(tmp != NULL, CPL_ERROR_NULL_INPUT, NULL);
01113 
01114     cpl_error_ensure(strstr(exe, "gnuplot"), CPL_ERROR_UNSUPPORTED_MODE,
01115                      return NULL, "%s", exe);
01116 
01117     data = fopen(tmp, "w");
01118 
01119     cpl_error_ensure(data != NULL, CPL_ERROR_FILE_IO, return NULL,
01120                      "%s", tmp);
01121 
01122     plot = cpl_malloc(sizeof(irplib_plot));
01123 
01124     plot->exe  = exe;
01125     plot->tmp  = tmp;
01126     plot->data = data;
01127 
01128     if (irplib_mplot_puts(plot, options)) {
01129         (void)irplib_mplot_close(plot, "");
01130         cpl_ensure(0, cpl_error_get_code(), NULL);
01131     }
01132 
01133     return plot;
01134 }
01135 
01136 /*----------------------------------------------------------------------------*/
01163 /*----------------------------------------------------------------------------*/
01164 static irplib_plot * irplib_image_open(const char * options)
01165 {
01166     irplib_plot * plot;
01167     const char * exe = irplib_mplot_imager();
01168     const char * tmp = IRPLIB_PLOT_TMPFILE;
01169     FILE * data;
01170 
01171 
01172     cpl_ensure(exe != NULL, CPL_ERROR_NULL_INPUT, NULL);
01173     cpl_ensure(tmp != NULL, CPL_ERROR_NULL_INPUT, NULL);
01174 
01175     data = fopen(tmp, "w");
01176 
01177     cpl_error_ensure(data != NULL, CPL_ERROR_FILE_IO, return NULL,
01178                      "%s", tmp);
01179 
01180     plot = cpl_malloc(sizeof(irplib_plot));
01181 
01182     plot->exe  = exe;
01183     plot->tmp  = tmp;
01184     plot->data = data;
01185 
01186     if (irplib_mplot_puts(plot, options)) {
01187         (void)irplib_mplot_close(plot, "");
01188         cpl_ensure(0, cpl_error_get_code(), NULL);
01189     }
01190 
01191     return plot;
01192 }
01193 
01194 /*----------------------------------------------------------------------------*/
01205 /*----------------------------------------------------------------------------*/
01206 static cpl_error_code irplib_mplot_close(irplib_plot * plot,
01207                                          const char  * options)
01208 {
01209     cpl_error_code error;
01210 
01211 
01212     cpl_ensure_code(plot != NULL, CPL_ERROR_NULL_INPUT);
01213 
01214     error = irplib_mplot_puts(plot, options);
01215 
01216     assert(plot->data != NULL);
01217     assert(plot->tmp != NULL);
01218     assert(plot->exe != NULL);
01219 
01220     if (fclose(plot->data) != 0) {
01221         error = CPL_ERROR_FILE_IO;
01222         cpl_error_set(cpl_func, error);
01223     }
01224 
01225     if (!error) {
01226         /* Note: The portability of this plotting module is limited by the
01227            portability of the following command (which is likely to be valid on
01228            any kind of UNIX platform). We use 'exec' to reduce the number of
01229            child processes created. */
01230         const char * command = cpl_sprintf("exec <%s %s", plot->tmp, plot->exe);
01231         const int nstat = system(command);
01232 
01233         if (nstat != 0) {
01234             error = CPL_ERROR_FILE_IO;
01235             cpl_error_set_message(cpl_func, error, "system('%s') returned %d",
01236                                   command ? command : "<NULL>", nstat);
01237         }
01238 
01239         cpl_free((void *)command); /* cast inserted to suppress warning about
01240                                       deallocating const objects which CPL does
01241                                       not support */
01242     }
01243     remove(plot->tmp);
01244 
01245     cpl_free(plot);
01246     cpl_ensure_code(!error, error);
01247 
01248     return CPL_ERROR_NONE;
01249 }
01250 
01251 /*----------------------------------------------------------------------------*/
01263 /*----------------------------------------------------------------------------*/
01264 static cpl_error_code irplib_mplot_puts(irplib_plot * plot, const char * cmd)
01265 {
01266 
01267     if (cmd == NULL || strlen(cmd) == 0) return CPL_ERROR_NONE;
01268 
01269     cpl_ensure_code(plot != NULL, CPL_ERROR_NULL_INPUT);
01270 
01271     assert(plot->data != NULL);
01272 
01273     cpl_ensure_code(fputs(cmd, plot->data) >= 0, CPL_ERROR_FILE_IO);
01274 
01275     return CPL_ERROR_NONE;
01276 }
01277 
01278 /*----------------------------------------------------------------------------*/
01291 /*----------------------------------------------------------------------------*/
01292 static cpl_error_code irplib_mplot_write(irplib_plot     *   plot, 
01293                                          const char      *   buffer,
01294                                          size_t              length)
01295 {
01296     cpl_ensure_code(plot   != NULL, CPL_ERROR_NULL_INPUT);
01297     cpl_ensure_code(buffer != NULL, CPL_ERROR_NULL_INPUT);
01298     cpl_ensure_code(length > 0,     CPL_ERROR_ILLEGAL_INPUT);
01299 
01300     assert(plot->data != NULL);
01301 
01302     cpl_ensure_code(fwrite(buffer, 1, length, plot->data) == length,
01303                     CPL_ERROR_FILE_IO);
01304 
01305     return CPL_ERROR_NONE;
01306 }

Generated on Fri Apr 18 14:11:41 2008 for UVES Pipeline Reference Manual by  doxygen 1.5.1