/* NIGHTFALL Light Curve Synthesis Program */
/* Copyright (C) 1998 Rainer Wichmann */
/* */
/* This program is free software; you can redistribute it */
/* and/or modify */
/* it under the terms of the GNU General Public License as */
/* published by */
/* the Free Software Foundation; either version 2 of the License, or */
/* (at your option) any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program; if not, write to the Free Software */
/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
+ this is a library of functions that somehow emulate the
+ PGPLOT calls in 'nightfall'. Some of the emulated
+ functions are just dirty hacks. Display of images
+ is not possible with GNUPLOT
+
+ the different plotting 'philosophy' of GNUPLOT and PGPLOT
+ adds considerable complications
+
+ based on demo code in the gnuplot faq
+ for calling gnuplot from C using named pipes
+ pipes are opened in /tmp directory
+
+ animated mode requires three separate data pipes to run
+
+ for details about the arguments of these subroutines, see
+ the PGPLOT manual
*/
/* ==========================================================
*
* 'set no...' is deprecated syntax, new syntax is 'unset ...'
*
* ==========================================================
*/
#include <stdlib.h>
#include <sys/stat.h>
#ifdef HAVE_SYS_TIMERS_H
#include <sys/timers.h>
#endif
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <float.h>
#include "Light.h"
#ifdef HAVE_UNISTD_H
#include <sys/types.h>
#include <unistd.h>
#endif
#include <time.h>
#ifdef _WITH_GNUPLOT
static struct timespec sleep_req = { 0, 20000000 };
static struct timespec sleep_rem;
static int gnuSubpageflag = OFF; /* flag for multiplot */
static int gnuPageX = 0; /* # of pages in x (multiplot) */
static int gnuPageY = 0; /* # of pages in y (multiplot) */
static int gnuPageXn = 0; /* actual page in x (multiplot) */
static int gnuPageYn = 0; /* actual page in y (multiplot) */
static float gnuLw = 1.; /* linewidth */
static float gnuPs = 1.; /* pointsize */
static int gnuLt = 1; /* linetype */
static float gnuOrig_x, gnuOrig_y; /* origin location */
static float gnuSizex, gnuSizey; /* page size */
static float gnuMOrig_x, gnuMOrig_y; /* origin location / bookkeping */
static float gnuMSizex, gnuMSizey; /* page size / bookkeping */
static char gnuCommands[1024]; /* command pipe */
static char gnuData1[1024]; /* data pipe1 */
static char gnuData2[1024]; /* data pipe2 */
static char gnuData3[1024]; /* data pipe3 */
static char gnuData4[1024]; /* data pipe4 */
static FILE *gnustr, *gnudat1, *gnudat2; /* pipe filehandles */
static FILE *gnudat3, *gnudat4; /* pipe filehandles */
static pid_t childPid; /* PID of forked process */
static pid_t processGroup; /* PID of forked process */
static char sig_msg[64]; /* signal name */
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Return signal name
@param (void)
@return (void)
@heading Signal Handling
*******************************************************************/
char * nf_signame(int signum)
{
switch (signum)
{
#ifdef SIGHUP
case SIGHUP: return "Hangup";
#endif
#ifdef SIGINT
case SIGINT: return "Interrupt";
#endif
#ifdef SIGQUIT
case SIGQUIT: return "Quit";
#endif
#ifdef SIGILL
case SIGILL: return "Illegal instruction";
#endif
#ifdef SIGTRAP
case SIGTRAP: return "Trace/breakpoint trap";
#endif
#ifdef SIGABRT
case SIGABRT: return "IOT trap/Abort";
#endif
#ifdef SIGBUS
case SIGBUS: return "Bus error";
#endif
#ifdef SIGFPE
case SIGFPE: return "Floating point exception";
#endif
#ifdef SIGKILL
case SIGKILL: return "Killed";
#endif
#ifdef SIGUSR1
case SIGUSR1: return "User defined signal 1";
#endif
#ifdef SIGSEGV
case SIGSEGV: return "Segmentation fault";
#endif
#ifdef SIGUSR2
case SIGUSR2: return "User defined signal 2";
#endif
#ifdef SIGPIPE
case SIGPIPE: return "Broken pipe";
#endif
#ifdef SIGALRM
case SIGALRM: return "Alarm clock";
#endif
#ifdef SIGTERM
case SIGTERM: return "Terminated";
#endif
#ifdef SIGSTKFLT
case SIGSTKFLT: return "Stack fault";
#endif
#ifdef SIGCHLD
case SIGCHLD: return "Child exited";
#endif
#ifdef SIGCONT
case SIGCONT: return "Continued";
#endif
#ifdef SIGSTOP
case SIGSTOP: return "Stopped (signal)";
#endif
#ifdef SIGTSTP
case SIGTSTP: return "Stopped";
#endif
#ifdef SIGTTIN
case SIGTTIN: return "Stopped (tty input)";
#endif
#ifdef SIGTTOU
case SIGTTOU: return "Stopped (tty output)";
#endif
#ifdef SIGURG
case SIGURG: return "Urgent condition";
#endif
#ifdef SIGXCPU
case SIGXCPU: return "CPU time limit exceeded";
#endif
#ifdef SIGXFSZ
case SIGXFSZ: return "File size limit exceeded";
#endif
#ifdef SIGVTALRM
case SIGVTALRM: return "Virtual time alarm";
#endif
#ifdef SIGPROF
case SIGPROF: return "Profile signal";
#endif
#ifdef SIGWINCH
case SIGWINCH: return "Window size changed";
#endif
#ifdef SIGIO
case SIGIO: return "Possible I/O";
#endif
#ifdef SIGPWR
case SIGPWR: return "Power failure";
#endif
#ifdef SIGUNUSED
case SIGUNUSED: return "Unused signal";
#endif
}
sprintf (sig_msg, "unknown signal (%8d)", signum);
return sig_msg;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Handle signals, cleanup FIFO's on abnormal termination
@param (void)
@return (void)
@heading Signal Handling
*******************************************************************/
void gnu_sighandler (int signal)
{
if (Flags.plotOpened == ON) {
Flags.plotOpened = OFF;
cpgend();
}
#ifdef HAVE_GNOME
if (Flags.interactive == ON)
doQuit();
#endif
/* is it safe to use fprintf() in a signal handler ?
fprintf(stderr,"** SIGHANDLE **: caught signal: %s ...\n",
nf_signame(signal));
fprintf(stderr," ... cleanup and exit to system \n");
*/
fputs("** SIGHANDLE **: caught signal: ", stderr);
fputs(nf_signame(signal), stderr);
fputs("\n", stderr);
NF_MPI_Abort();
exit(EXIT_FAILURE);
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Additional function required at plot start
@param (void)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void gnu_end()
{
fprintf(gnustr, "unset multiplot\n");
fflush(gnustr);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Additional function required at temorary plot end
@param (void)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void gnu_start()
{
fprintf(gnustr, "set multiplot\n");
fflush(gnustr);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Image display
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgimag(const float *a, int idim, int jdim, int i1, int i2, int j1,
int j2, float a1, float a2, const float *tr)
{
/* there is no such resource in GNUPLOT */
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Contour plotting
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgcont(const float *a, int xdim, int ydim, int x1, int x2, int y1,
int y2, const float *c, int nc, const float *tr)
{
register unsigned int i, j; /* loop variables */
register unsigned int l; /* loop variables */
float xfactor = 60.0; /* scale factor x */
float yfactor = 60.0; /* scale factor y */
float xstart = -1.0; /* start x */
float ystart = -1.0; /* start y */
if (xdim == _CHI_SCANS_) {
xfactor = 1.0/tr[1];
yfactor = 1.0/tr[5];
xstart = tr[0] + 0.5*tr[1];
ystart = tr[3] + 0.5*tr[5];
}
fprintf(gnustr,"unset surface\n");
fprintf(gnustr,"set contour\n");
fprintf(gnustr,"set view 0., 0., 1.5\n");
/* put commands in command pipe and data in data pipe */
fprintf(gnustr,"set cntrparam cubicspline\n");
fprintf(gnustr,"set cntrparam levels discrete %f, %f, %f, %f, %f\n",
*(c),
*(c + 1),
*(c + 2),
*(c + 3),
*(c + 4));
fprintf(gnustr,"clear\n");
fprintf(gnustr,"splot '%s' index 0 notitle w lines \n", gnuData4);
fflush(gnustr);
/* this fopen must occur AFTER gnuplot has already */
/* tried to open the pipe for reading */
gnudat4 = fopen(gnuData4, "w");
if(!gnudat4) perror (_("could not open pipe"));
l = (xdim/10)*10;
for (i=0; i < ydim; ++i) {
/* some dynamic loop unrolling */
j= 0;
while (j < l) {
fprintf(gnudat4,"%7.4f %7.4f %7.4f\n",
j/xfactor + xstart, i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j)) );
fprintf(gnudat4,"%7.4f %7.4f %7.4f\n",
(1+j)/xfactor + xstart, i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j + 1)) );
fprintf(gnudat4,"%7.4f %7.4f %7.4f\n",
(2+j)/xfactor + xstart, i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j + 2)) );
fprintf(gnudat4,"%7.4f %7.4f %7.4f\n",
(3+j)/xfactor + xstart, i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j + 3)) );
fprintf(gnudat4,"%7.4f %7.4f %7.4f\n",
(4+j)/xfactor + xstart, i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j + 4)) );
fprintf(gnudat4,"%7.4f %7.4f %7.4f\n",
(5+j)/xfactor + xstart, i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j + 5)) );
fprintf(gnudat4,"%7.4f %7.4f %7.4f\n",
(6+j)/xfactor + xstart, i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j + 6)) );
fprintf(gnudat4,"%7.4f %7.4f %7.4f\n",
(7+j)/xfactor + xstart, i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j + 7)) );
fprintf(gnudat4,"%7.4f %7.4f %7.4f\n",
(8+j)/xfactor + xstart, i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j + 8)) );
fprintf(gnudat4,"%7.4f %7.4f %7.4f\n",
(9+j)/xfactor + xstart, i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j + 9)) );
/*********************************************
fprintf(stderr,"%7.4f %7.4f %7.4f\n",
j/xfactor + xstart, i/yfactor + ystart,
*(a + xdim*i + j));
fprintf(stderr,"%7.4f %7.4f %7.4f\n",
(1+j)/xfactor + xstart, i/yfactor + ystart,
*(a + xdim*i + j + 1));
fprintf(stderr,"%7.4f %7.4f %7.4f\n",
(2+j)/xfactor + xstart, i/yfactor + ystart,
*(a + xdim*i + j + 2));
fprintf(stderr,"%7.4f %7.4f %7.4f\n",
(3+j)/xfactor + xstart, i/yfactor + ystart,
*(a + xdim*i + j + 3));
fprintf(stderr,"%7.4f %7.4f %7.4f\n",
(4+j)/xfactor + xstart, i/yfactor + ystart,
*(a + xdim*i + j + 4));
fprintf(stderr,"%7.4f %7.4f %7.4f\n",
(5+j)/xfactor + xstart, i/yfactor + ystart,
*(a + xdim*i + j + 5));
fprintf(stderr,"%7.4f %7.4f %7.4f\n",
(6+j)/xfactor + xstart, i/yfactor + ystart,
*(a + xdim*i + j + 6));
fprintf(stderr,"%7.4f %7.4f %7.4f\n",
(7+j)/xfactor + xstart, i/yfactor + ystart,
*(a + xdim*i + j + 7));
fprintf(stderr,"%7.4f %7.4f %7.4f\n",
(8+j)/xfactor + xstart, i/yfactor + ystart,
*(a + xdim*i + j + 8));
fprintf(stderr,"%7.4f %7.4f %7.4f\n",
(9+j)/xfactor + xstart, i/yfactor + ystart,
*(a + xdim*i + j + 9));
********************************************/
j = j + 10;
}
if (j < xdim) {
switch (xdim -j)
{
case 9: fprintf(gnudat4,"%7.4f %7.4f %7.4f\n", j/xfactor + xstart,
i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j))); ++j;
case 8: fprintf(gnudat4,"%7.4f %7.4f %7.4f\n", j/xfactor + xstart,
i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j))); ++j;
case 7: fprintf(gnudat4,"%7.4f %7.4f %7.4f\n", j/xfactor + xstart,
i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j))); ++j;
case 6: fprintf(gnudat4,"%7.4f %7.4f %7.4f\n", j/xfactor + xstart,
i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j))); ++j;
case 5: fprintf(gnudat4,"%7.4f %7.4f %7.4f\n", j/xfactor + xstart,
i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j))); ++j;
case 4: fprintf(gnudat4,"%7.4f %7.4f %7.4f\n", j/xfactor + xstart,
i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j))); ++j;
case 3: fprintf(gnudat4,"%7.4f %7.4f %7.4f\n", j/xfactor + xstart,
i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j))); ++j;
case 2: fprintf(gnudat4,"%7.4f %7.4f %7.4f\n", j/xfactor + xstart,
i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j))); ++j;
case 1: fprintf(gnudat4,"%7.4f %7.4f %7.4f\n", j/xfactor + xstart,
i/yfactor + ystart,
MAX(-99., *(a + xdim*i + j))); ++j;
default: break;
}
}
fprintf(gnudat4," \n");
}
fclose(gnudat4);
/* to avoid 'broken pipe' errors */
nanosleep (&sleep_req, &sleep_rem);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Image display - wedge
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgwedg(const char *side, float disp, float width, float fg, float bg,
const char *label)
{
/* there is no such resource in GNUPLOT */
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Set line size
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgsls(int fnt)
{
/* not required */
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Set character size
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgscf(int fnt)
{
/* not required */
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Viewport size default
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgvstd()
{
cpgsvp(0.1, 0.9, 0.1, 0.9);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Text label
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgtext(float xpos, float ypos, const char *label)
{
fprintf(gnustr,"set label '%s' at first %f, %f \n", label, xpos, ypos );
fflush(gnustr);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Set title and axis labels
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpglab(const char *xlbl, const char *ylbl, const char *toplbl)
{
fprintf(gnustr,"set title '%s' \n", toplbl);
fprintf(gnustr,"set xlabel '%s' \n", xlbl);
fprintf(gnustr,"set ylabel '%s' \n", ylbl);
fflush(gnustr);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Draw a line
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgline(int n, const float *xpts, const float *ypts)
{
int i; /* loop variable */
/* put commands in command pipe and data in data pipe */
fprintf(gnustr,"plot '%s' notitle w lines \n", gnuData1);
fflush(gnustr);
/* this fopen must occur AFTER gnuplot has already */
/* tried to open the pipe for reading */
gnudat1 = fopen(gnuData1, "w");
if(!gnudat1) perror (_("could not open pipe"));
for(i = 0; i < n; ++i) {
fprintf(gnudat1,"%8.5g %8.5g\n", xpts[i], ypts[i]);
}
fclose(gnudat1);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Plot points
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgpt(int n, const float *xpts, const float *ypts, int npt)
{
int i; /* loop variable */
/* put commands in command pipe and data in data pipe */
fprintf(gnustr,"plot '%s' notitle w points ps %f \n",
gnuData3, gnuPs);
fflush(gnustr);
/* this fopen must occur AFTER gnuplot has already */
/* tried to open the pipe for reading */
gnudat3 = fopen(gnuData3, "w");
if(!gnudat3) perror (_("could not open pipe"));
for(i = 0; i < n; ++i)
fprintf(gnudat3,"%8.5g %8.5g\n", xpts[i], ypts[i]);
fclose(gnudat3);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Plot points (two datasets)
@tip not in PGPLOT
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgpt2(int n, int n2, const float *x1pts, const float *y1pts,
const float *x2pts, const float *y2pts)
{
int i; /* loop variable */
/* put commands in command pipe and data in data pipe */
fprintf(gnustr,
"plot '%s' notitle w points pt 0, '%s' notitle w points pt 0\n",
gnuData1, gnuData2);
fflush(gnustr);
/* this fopen must occur AFTER gnuplot has already */
/* tried to open the pipe for reading */
gnudat1 = fopen(gnuData1, "w");
if(!gnudat1) perror (_("could not open pipe"));
for(i = 0; i < n; ++i) {
fprintf(gnudat1,"%8.5g %8.5g\n", x1pts[i], y1pts[i]);
}
fclose(gnudat1);
gnudat2 = fopen(gnuData2, "w");
if(!gnudat2) perror (_("could not open pipe"));
for(i = 0; i < n2; ++i) {
fprintf(gnudat2,"%8.5g %8.5g\n", x2pts[i], y2pts[i]);
}
fclose(gnudat2);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Draw lines (two datasets)
@tip not in PGPLOT
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgline2(int n, int n2, const float *x1pts, const float *y1pts,
const float *x2pts, const float *y2pts)
{
int i; /* loop variable */
/* put commands in command pipe and data in data pipe */
fprintf(gnustr,
"plot '%s' index 0:1 notitle w lines lt 2\n",
gnuData2);
fflush(gnustr);
/* this fopen must occur AFTER gnuplot has already */
/* tried to open the pipe for reading */
gnudat2 = fopen(gnuData2, "w");
if(!gnudat2) perror (_("could not open pipe"));
for(i = 0; i < n; ++i) {
fprintf(gnudat2,"%8.5g %8.5g\n", x1pts[i], y1pts[i]);
}
fprintf(gnudat2," \n");
fprintf(gnudat2," \n");
for(i = 0; i < n2; ++i) {
fprintf(gnudat2,"%8.5g %8.5g\n", x2pts[i], y2pts[i]);
}
fclose(gnudat2);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Draw points + line (three datasets)
@tip not in PGPLOT
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgline2pt(int n, int n2, int n3, const float *x1pts, const float *y1pts,
const float *x2pts, const float *y2pts,
const float *x3pts, const float *y3pts)
{
int i; /* loop variable */
/* put commands in command pipe and data in data pipe */
/* ------------- POINTS FIRST, LINES SECOND --------------- */
fprintf(gnustr,
"plot '%s' notitle w points ps %f, '%s' index 0:1 notitle w lines lt 2\n",
gnuData1, gnuPs, gnuData2);
fflush(gnustr);
/* this fopen must occur AFTER gnuplot has already */
/* tried to open the pipe for reading */
gnudat1 = fopen(gnuData1, "w");
for(i = 0; i < n3; ++i) {
fprintf(gnudat1,"%8.5g %8.5g\n", x3pts[i], y3pts[i]);
}
fclose(gnudat1);
gnudat2 = fopen(gnuData2, "w");
if(!gnudat2) perror (_("could not open pipe"));
for(i = 0; i < n; ++i) {
fprintf(gnudat2,"%8.5g %8.5g\n", x1pts[i], y1pts[i]);
}
fprintf(gnudat2," \n");
fprintf(gnudat2," \n");
for(i = 0; i < n2; ++i) {
fprintf(gnudat2,"%8.5g %8.5g\n", x2pts[i], y2pts[i]);
}
fclose(gnudat2);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Draw points + line (two datasets)
@tip not in PGPLOT
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpglinept(int n, int n2, const float *x1pts, const float *y1pts,
const float *x2pts, const float *y2pts)
{
int i; /* loop variable */
/* put commands in command pipe and data in data pipe */
fprintf(gnustr,
"plot '%s' notitle w lines, '%s' notitle w points ps %f\n",
gnuData1, gnuData2, gnuPs);
fflush(gnustr);
/* this fopen must occur AFTER gnuplot has already */
/* tried to open the pipe for reading */
gnudat1 = fopen(gnuData1, "w");
if(!gnudat1) perror (_("could not open pipe"));
for(i = 0; i < n; ++i) {
fprintf(gnudat1,"%f %f\n", x1pts[i], y1pts[i]);
}
fclose(gnudat1);
gnudat2 = fopen(gnuData2, "w");
if(!gnudat2) perror (_("could not open pipe"));
for(i = 0; i < n2; ++i) {
fprintf(gnudat2,"%f %f\n", x2pts[i], y2pts[i]);
}
fclose(gnudat2);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Set box type
@tip only BCST, BCMST, ABCNST supported
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgbox(const char *xopt, float xtick, int nxsub, const char *yopt,
float ytick, int nysub)
{
/* set tickmarks */
if (xtick != 0.0) fprintf(gnustr, "set xtics %10.2f \n", xtick);
if (strcmp("BCMST", yopt) != 0)
if (ytick != 0.0) fprintf(gnustr, "set ytics %10.2f \n", ytick);
/* required: support for BCST, BCMST, ABCNST */
if (strcmp("BCST", xopt) == 0) {
fprintf(gnustr, "set xtics (\"\" 0)\n");
}
if (strcmp("BCST", yopt) == 0) {
fprintf(gnustr, "set ytics (\"\" 0)\n");
}
if (strcmp("BCNST", xopt) == 0) {
fprintf(gnustr, "set xtics \n");
if (xtick != 0.0) fprintf(gnustr, "set xtics %10.5g \n", xtick);
}
if (strcmp("BCNST", yopt) == 0) {
fprintf(gnustr, "set ytics \n");
if (ytick != 0.0) fprintf(gnustr, "set ytics %10.5g \n", ytick);
}
if (strcmp("BCMST", xopt) == 0) {
fprintf(gnustr, "set xtics (\"\" 0)\n");
fprintf(gnustr, "set x2tics \n");
if (xtick != 0.0) fprintf(gnustr, "set x2tics %10.5g \n", xtick);
}
if (strcmp("BCMST", yopt) == 0) {
fprintf(gnustr, "set ytics (\"\" 0)\n");
/* for some reason, range is not properly set for y2tics */
/* fprintf(gnustr, "set y2tics \n"); */
/* fprintf(gnustr, "set y2range [*:*]\n"); */
if (ytick != 0.0)
/* fprintf(gnustr, "set y2tics %10.5g \n", ytick); */
fprintf(gnustr, "set ytics %10.5g \n", ytick);
}
if (strcmp("ABCNST", xopt) == 0) {
fprintf(gnustr, "set xtics \n");
fprintf(gnustr, "set xzeroaxis \n");
}
if (strcmp("ABCNST", yopt) == 0) {
fprintf(gnustr, "set ytics \n");
fprintf(gnustr, "set yzeroaxis \n");
}
fflush(gnustr);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Query plot window location
@tip no support for units
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgqvp(int units, float *x1, float *x2, float *y1, float *y2)
{
/* no support for units */
if (units != 0) {
WARNING(_("PGPLOT emulation: cpgqvp has no support for units"));
} else {
*x1 = gnuMOrig_x; *x2 = gnuMOrig_x + gnuMSizex;
*y1 = gnuMOrig_y; *y2 = gnuMOrig_y + gnuMSizey;
}
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Text annotation
@tip hardcoded locations of annotations
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgmtxt(const char *side, float disp, float coord, float fjust,
const char *text)
{
float x = 0., y = 0.; /* the text locations */
if (strcmp("T", side) == 0) {
y = 0.85; x = 0.5;
} else if (strcmp("B", side) == 0) {
y = 0.05; x = 0.8;
} else {
WARNING(_("PGPLOT emulation: cpgmtxt 'side' argument not valid"));
}
fprintf(gnustr,
"set label \"%s\" at screen %5.2f, %5.2f center\n",
text, x, y);
fflush(gnustr);
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Set plot window with aspect ratio 1.0
@tip works in GNUPLOT only with no title
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgwnad(float xleft, float xright, float ybot, float ytop)
{
float xsize; /* size in x */
float ysize; /* size in y */
float max; /* max of both */
/* set plot ranges */
fprintf(gnustr, "set xrange [%10.5g:%10.5g] \n", xleft, xright );
fprintf(gnustr, "set yrange [%10.5g:%10.5g] \n", ybot, ytop );
/* calculate sizes and their maximum */
xsize = (xright - xleft)/gnuSizex;
ysize = (ytop - ybot)/gnuSizey;
max = MAX(xsize,ysize);
/* adjust aspect */
ysize = 1.375 * (ytop - ybot)/max;
xsize = (xright - xleft)/max;
/* adjust aspect of subpages */
if (gnuSubpageflag == ON) {
ysize = ysize/gnuPageY; xsize = xsize/gnuPageX;
}
/* store for bookkeeping */
gnuMSizey = ysize; gnuMSizex = xsize;
/* set size */
fprintf(gnustr, "set size %5.2f, %5.2f\n", xsize, ysize );
fflush(gnustr); fflush(gnustr);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Set plot window
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgswin(float xleft, float xright, float ybot, float ytop)
{
fprintf(gnustr, "set xrange [%10.5g:%10.5g] \n", xleft, xright );
fprintf(gnustr, "set yrange [%10.5g:%10.5g] \n", ybot, ytop );
fprintf(gnustr, "unset autoscale\n");
fflush(gnustr);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Set color
@tip Color is linetype in GNUPLOT
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgsci(int lw)
{
/* color = linetype in gnuplot */
gnuLt = lw;
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Set linewidth
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgslw(float lw)
{
gnuLw = lw;
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Set point size
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgsch(float lw)
{
gnuPs = lw;
fprintf(gnustr, "set pointsize %5.2f \n", lw);
fflush(gnustr);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Set viewport
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgsvp(float xleft, float xright, float ybot, float ytop)
{
float xsize, ysize; /* size of viewport */
float xoff, yoff; /* offset to origin */
/* compute sizes and offset */
xoff = xleft;
yoff = ybot;
xsize = xright - xleft;
ysize = ytop - ybot;
/* store for bookkeeping */
gnuSizex = xsize;
gnuSizey = ysize;
/* compute size and offset to origin for subpage */
if (gnuSubpageflag == ON) {
xoff = gnuOrig_x + xoff/gnuPageX;
yoff = gnuOrig_y + yoff/gnuPageY;
ysize = ysize/gnuPageY;
xsize = xsize/gnuPageX;
}
/* store for bookkeeping */
gnuMSizey = ysize;
gnuMSizex = xsize;
gnuMOrig_y = yoff;
gnuMOrig_x = xoff;
/* set viewport and initialize */
fprintf(gnustr, "set title ""\n");
fprintf(gnustr, "set xlabel\n");
fprintf(gnustr, "set ylabel\n");
fprintf(gnustr, "set xrange [*:*]\n");
fprintf(gnustr, "set yrange [*:*]\n");
fprintf(gnustr, "set autoscale\n");
fprintf(gnustr, "unset xzeroaxis \n");
fprintf(gnustr, "unset yzeroaxis \n");
fprintf(gnustr, "unset y2tics \n");
fprintf(gnustr, "unset x2tics \n");
fprintf(gnustr, "unset label\n");
fprintf(gnustr, "set mxtics 5\n");
fprintf(gnustr, "set mytics 5\n");
fprintf(gnustr, "set origin %5.2f, %5.2f\n", xoff, yoff );
fprintf(gnustr, "set size %5.2f, %5.2f\n", xsize, ysize );
fflush(gnustr);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Set viewport
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgenv(float xmin, float xmax, float ymin, float ymax, int just, int axis)
{
cpgsvp(xmin, xmax, ymin, ymax);
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Set subpage
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgsubp(int a, int b)
{
/* store number of subpages */
gnuPageX = a;
gnuPageY = b;
/* initialize current subpage */
gnuPageXn = 0;
gnuPageYn = -1;
fprintf(gnustr, "unset multiplot\n");
fprintf(gnustr, "set multiplot\n");
fprintf(gnustr, "set origin 0.0, 0.0\n");
fflush(gnustr);
/* initialize origin of current subpage */
gnuMOrig_y = 0.; gnuMOrig_x = 0.;
gnuSubpageflag = ON;
return;
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Goto next page
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgpage()
{
float orig_x, orig_y; /* origin of next page */
orig_y = 0.0;
orig_x = 0.0;
if (gnuSubpageflag == ON) {
/* ------------ multiplot ------------------------------ */
/* page n times offset */
if (gnuPageYn < gnuPageY) ++gnuPageYn;
if (gnuPageYn == gnuPageY) {
gnuPageYn = 0;
++gnuPageXn;
if (gnuPageXn == gnuPageX) {
gnuSubpageflag = OFF;
gnuPageXn = 0; gnuPageYn = 0;
fprintf(gnustr, "unset multiplot\n");
fprintf(gnustr, "set multiplot\n");
fflush(gnustr);
}
}
gnuOrig_x = orig_x + gnuPageXn * (1.0 / gnuPageX);
gnuOrig_y = orig_y + gnuPageYn * (1.0 / gnuPageY);
gnuMOrig_y = gnuOrig_y; gnuMOrig_x = gnuOrig_x;
fprintf(gnustr, "set origin %5.2f ,%5.2f\n", gnuOrig_x, gnuOrig_y);
fflush(gnustr);
} else {
/* ------------ single page ---------------------------- */
gnuMOrig_y = 0.; gnuMOrig_x = 0.;
fprintf(gnustr, "unset multiplot\n");
fprintf(gnustr, "set multiplot\n");
fprintf(gnustr, "set origin 0.0 ,0.0\n");
fflush(gnustr);
}
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Open plot device
@param (see PGPLOT manual)
@return (int) The error code
@heading PGPLOT emulation
*******************************************************************/
int cpgopen(char *s)
{
char gnu_geometry[256]; /* Window geometry */
int result; /* Error code */
char tmpdir[1024]; /* tmp directory */
struct sigaction act, oldact; /* signal handling */
/* xwindow already open */
if (strcmp("/XSERVE", s) == 0 && Flags.plotOpened == ON) {
fprintf(gnustr, "set terminal x11\n");
fflush(gnustr);
/* seems to be reqired unfortunately */
nanosleep (&sleep_req, &sleep_rem);
fprintf(gnustr, "set terminal x11\n");
fprintf(gnustr, "unset mouse\n"); /* requires 3.8c+ */
fflush(gnustr);
return (1);
}
else if (Flags.plotOpened == ON) {
fprintf(gnustr, "set terminal postscript color\n");
fprintf(gnustr, "set output \"%s\" \n", Out_Plot_File);
fflush(gnustr);
return (1);
}
/* get tmp directory */
if (getenv("TEMPDIR") != NULL) strncpy(tmpdir, getenv("TEMPDIR"), 960);
if (getenv("TMPDIR") != NULL) strncpy(tmpdir, getenv("TMPDIR"), 960);
else strcpy(tmpdir, "/tmp");
strcpy(gnuCommands, tmpdir);
strcpy(gnuData1, tmpdir);
strcpy(gnuData2, tmpdir);
strcpy(gnuData3, tmpdir);
strcpy(gnuData4, tmpdir);
/* create command pipe */
sprintf(gnuCommands + strlen(gnuCommands), "/gnuplot.input.%ld",
(long) getpid() );
result = mkfifo(gnuCommands, 0666);
if(result) perror (_("could not create command pipe"));
/* create first data pipe */
sprintf(gnuData1 + strlen(gnuData1), "/gnuplot.data1.%ld",
(long) getpid() );
result = mkfifo(gnuData1, 0666);
if(result) perror (_("could not create data1 pipe"));
/* create second data pipe */
sprintf(gnuData2 + strlen(gnuData2), "/gnuplot.data2.%ld",
(long) getpid() );
result = mkfifo(gnuData2, 0666);
if(result) perror (_("could not create data2 pipe"));
/* create third data pipe */
sprintf(gnuData3 + strlen(gnuData3), "/gnuplot.data3.%ld",
(long) getpid() );
result = mkfifo(gnuData3, 0666);
if(result) perror (_("could not create data3 pipe"));
/* create forth data pipe */
sprintf(gnuData4 + strlen(gnuData4), "/gnuplot.data4.%ld",
(long) getpid() );
result = mkfifo(gnuData4, 0666);
if(result) perror (_("could not create data4 pipe"));
/* fork a process for GNUPLOT */
childPid = fork();
/* FIXME: does this affect the MPI environment ? */
if ( childPid == -1 ) {
perror (_("unable to fork"));
_exit (EXIT_FAILURE);
return 0;
}
if ( childPid == 0 ){
/* ------------ child process ----------------------------- */
processGroup = getpid();
setpgid(0, processGroup);
if (getenv("GNUPLOT_GEOMETRY") == NULL)
strncpy(gnu_geometry, GNU_GEOMETRY, 255);
else
strncpy(gnu_geometry, getenv("GNUPLOT_GEOMETRY"), 255);
gnu_geometry[255] = '\0';
/* start GNUPLOT and exit */
if (strcmp("/XSERVE", s) == 0) {
/*
fprintf(stderr, "gnuplot -persist -geometry %s %s\n",
gnu_geometry, gnuCommands);
*/
execlp("gnuplot", "gnuplot", "-persist", "-geometry",
gnu_geometry, gnuCommands, NULL);
} else {
/*
fprintf(stderr, "gnuplot -geometry %s %s\n",
gnu_geometry, gnuCommands);
*/
execlp("gnuplot", "gnuplot", "-geometry",
gnu_geometry, gnuCommands, NULL);
}
/* execlp only returns if an error has occured */
perror (_("could not execute gnuplot"));
_exit(EXIT_FAILURE);
return 0;
} else {
/* ------------- parent process --------------------------- */
if (Flags.interactive == ON)
setpgid ( childPid, processGroup);
/* open command pipe for write and return */
gnustr = fopen(gnuCommands, "w");
if(!gnustr) perror (_("could not open command pipe"));
/* set up a signal handler so we can clean up if killed */
act.sa_handler = &gnu_sighandler; /* signal action */
sigemptyset( &act.sa_mask ); /* set an empty mask */
act.sa_flags = 0; /* init sa_flags */
#ifdef SIGHUP
sigaction(SIGHUP, &act, &oldact);
#endif
#ifdef SIGINT
sigaction(SIGINT, &act, &oldact);
#endif
#ifdef SIGQUIT
sigaction(SIGQUIT, &act, &oldact);
#endif
#ifdef SIGILL
sigaction(SIGILL, &act, &oldact);
#endif
#ifdef SIGABRT
sigaction(SIGABRT, &act, &oldact);
#endif
#ifdef SIGSEGV
sigaction(SIGSEGV, &act, &oldact);
#endif
#ifdef SIGPIPE
sigaction(SIGPIPE, &act, &oldact);
#endif
#ifdef SIGTRAP
sigaction(SIGTRAP, &act, &oldact);
#endif
#ifdef SIGIOT
sigaction(SIGIOT, &act, &oldact);
#endif
#ifdef SIGTERM
sigaction(SIGTERM, &act, &oldact);
#endif
#ifdef SIGBUS
sigaction(SIGBUS, &act, &oldact);
#endif
#ifdef SIGIO
sigaction(SIGIO, &act, &oldact);
#endif
#ifdef SIGPOLL
sigaction(SIGPOLL, &act, &oldact);
#endif
#ifdef SIGXCPU
sigaction(SIGXCPU, &act, &oldact);
#endif
#ifdef SIGPWR
sigaction(SIGPWR, &act, &oldact);
#endif
if (strcmp("/XSERVE", s) == 0 || strcmp("/XNOP", s) == 0 ) {
fprintf(gnustr, "set terminal x11\n");
fprintf(gnustr, "unset mouse\n"); /* requires 3.8c+ */
fflush(gnustr);
} else {
fprintf(gnustr, "set terminal postscript color\n");
fprintf(gnustr, "set output \"%s\" \n", Out_Plot_File);
fflush(gnustr);
}
fprintf(gnustr, "set origin 0.0, 0.0\n");
fflush(gnustr);
gnuSubpageflag = OFF;
if (strcmp("/XSERVE", s) == 0) Flags.plotOpened = ON;
return(1);
}
}
/******************************************************************
@package nightfall
@author Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
@version 1.0
@short Close plot device
@param (see PGPLOT manual)
@return (void)
@heading PGPLOT emulation
*******************************************************************/
void cpgend()
{
/*
static char command[80], line[133], *linep, *token;
FILE *fp;
int try;
*/
fprintf(gnustr, "unset multiplot\n");
fflush(gnustr);
fprintf(gnustr, "unset multiplot\n");
fflush(gnustr);
fprintf(gnustr, "set output \n ");
fflush(gnustr);
/* ------- return if plot window is open ---------------- */
if (Flags.plotOpened == ON) {
fprintf(gnustr, "set terminal x11\n ");
fflush(gnustr);
return;
}
/* ------- else ---------------- */
/* required for proper closedown of pipes */
nanosleep (&sleep_req, &sleep_rem);
remove(gnuData1);
remove(gnuData2);
remove(gnuData3);
remove(gnuData4);
fclose(gnustr);
if (Flags.interactive == ON)
kill ( -childPid, SIGKILL);
else
kill ( childPid, SIGKILL);
remove(gnuCommands);
return;
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1