irplib_plot.c

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

Generated on Thu Nov 15 14:32:26 2007 for UVES Pipeline Reference Manual by  doxygen 1.5.1