Metropoli BBS
VIEWER: okplot.c MODE: TEXT (ASCII)
/***************************************************************************
 *		  Copyright (C) 1994  Charles P. Peterson                  *
 *	     4007 Enchanted Sun, San Antonio, Texas 78244-1254             *
 *              Email: Charles_P_Peterson@fcircus.sat.tx.us                *
 *                                                                         *
 *		  This is free software with NO WARRANTY.                  *
 *	      See gfft.c, or run program itself, for details.              *
 *		      Support is available for a fee.                      *
 ***************************************************************************
 *
 * Program:     gfft--General FFT analysis
 * File:        ok_plot.c
 * Purpose:     plot data (invoking separate plotter program)
 * Author:      Charles Peterson (CPP)
 * History:     24-November-1993 CPP; Created.
 *              14-July-1994 CPP (1.01); Give helpful notes on failure.
 *              9-Aug-94 CPP (1.10); Hidden3D now optional
 *              28-Aug-94 CPP (1.12); Use Z for Y in 3D
 *              12-Oct-94 CPP (1.15); Fix for log x in gnuplot, also correct
 *                precision for xrange specifications
 *              17-Jan-95 CPP (1.20); Size GNUPLOT shell nicely
 *               9-Feb-95 CPP (1.33); Allow multiple GNUPLOT sessions
 *              14-Feb-95 CPP (1.42); Allow freeform PlotCommands
 *
 * Comment:     Only gnuplot supported now; others may be added.
 *              There may be some system dependency here.
 *              Eventually, it is intended to be made system independent.
 *              Also, might add custom 'gfft' plotter.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifdef AMIGA
#include <dos/dos.h>
#include <clib/dos_protos.h>
#endif

#include "gfft.h"
#include "settings.h"

#define GPLOT_3D_LOG_BUG_WORKAROUND


int Old_File_Count = 0;  /* This may be read or reset to zero externally */
static char **Old_File_Name = NULL;
static BOOLEAN plotted_already = FALSE;
static BOOLEAN re_plotting = FALSE;

extern double LowestFrequencyWritten;
extern double HighestFrequencyWritten;

#ifdef AMIGA
extern int Shell_Height;
extern int Shell_Width;
#endif

static void do_ok_plot (BOOLEAN this_is_re_plot);

void do_re_plot (void)
{
/* Further checking could be included here */
    re_plotting = TRUE;
    do_ok_plot (TRUE);
}

void ok_plot (void)
{
    re_plotting = FALSE;
    do_ok_plot (FALSE);
}

static void do_ok_plot (BOOLEAN this_is_re_plot)
{
    static name_count = 0;
    char buffer[COMMAND_BUFFER_SIZE];
    FILE *comfile_ptr;
    FILE *gnuplot_comfile_ptr;
    char *save_name;
    double xrange[2];
    BOOLEAN restrict_xrange = FALSE;
    char plot_command_file_name[MAX_PLOT_COMMANDFILE_NAME];
    char gnuplot_command_file_name[MAX_PLOT_COMMANDFILE_NAME];

    plotted_already = TRUE;
    xrange[0] = LowestFrequencyWritten;
    xrange[1] = HighestFrequencyWritten;

    sprintf (plot_command_file_name, "%s%d", PLOT_COMMAND_FILE_NAME, 
	     ++name_count);
    sprintf (gnuplot_command_file_name, "%s%d", GNUPLOT_COMMAND_FILE_NAME,
	     name_count);

/**************************************************************************\
 * Write command file
\**************************************************************************/

    comfile_ptr = fopen (plot_command_file_name, "w");
    if (!comfile_ptr)
    {
	error_message (CANT_CREATE_PLOTTER_FILE);
	RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
    }

#ifdef AMIGA
    fprintf (comfile_ptr, "stack %d\n", GNUPLOT_STACKSIZE);
    fprintf (comfile_ptr,"echo \" \"\n");
    fprintf (comfile_ptr,
"echo \" Press <RETURN> to end plot display once it appears.\"\n");
    fprintf (comfile_ptr,"echo \" \"\n");
    fprintf (comfile_ptr,"%s%s%s",
"echo \" ",
"(All is OK now, but if gnuplot has a problem later, try fewer bins.)",
"\"\n");
    fprintf (comfile_ptr,"echo \" \"\n");
    fprintf (comfile_ptr,"echo \" Generating plot using GNUPLOT\"\n");
    fprintf (comfile_ptr,"echo \" \"\n");
    fprintf (comfile_ptr,
"echo \" Copyright(C) 1986 - 1993   Thomas Williams, Colin Kelley\"\n");
    fprintf (comfile_ptr,"wait 1\n");
    fprintf (comfile_ptr,"failat 1\n");  /* exit script on gnuplot error */
#endif

    fprintf (comfile_ptr,"gnuplot %s\n",
             gnuplot_command_file_name);

#ifdef AMIGA
    fprintf (comfile_ptr,"delete \"%s\" QUIET\n",gnuplot_command_file_name);
    fprintf (comfile_ptr,"endcli\n");
#endif

    fclose (comfile_ptr);

/**************************************************************************\
 * Write GNUPLOT command file
\**************************************************************************/

    gnuplot_comfile_ptr = fopen (gnuplot_command_file_name,"w");
    if (!gnuplot_comfile_ptr)
    {
	error_message (CANT_CREATE_PLOTTER_FILE);
	RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
    }
    if (Terminal && Terminal != NullString && strlen(Terminal))
    {
	fprintf (gnuplot_comfile_ptr, "set terminal %s\n", Terminal);
    }
    if (PlotOutput && PlotOutput != NullString && strlen(PlotOutput))
    {
	fprintf (gnuplot_comfile_ptr, "set output \'%s\'\n", PlotOutput);
    }
    if (!Time3D)
    {
	if (LowY != LOWEST_Y) fprintf (gnuplot_comfile_ptr, 
				       "set yrange [%g:]\n", LowY);
	if (HighY != HIGHEST_Y) fprintf (gnuplot_comfile_ptr, 
					 "set yrange [:%g]\n", HighY);
    }
    else   /* in 3d, amplitude is z */
    {
	if (LowY != LOWEST_Y) fprintf (gnuplot_comfile_ptr, 
				       "set zrange [%g:]\n", LowY);
	if (HighY != HIGHEST_Y) fprintf (gnuplot_comfile_ptr, 
					 "set zrange [:%g]\n", HighY);
    }
    if (LogX) fprintf (gnuplot_comfile_ptr, "set log x\n");
    if (LogY && !Time3D) fprintf (gnuplot_comfile_ptr, "set log y\n");
    if (LogY && Time3D) fprintf (gnuplot_comfile_ptr, "set log z\n");
    if (RotX != DEF_ROT_X)
    {
	fprintf (gnuplot_comfile_ptr, "set view %g\n", RotX);
    }
    if (RotZ != DEF_ROT_Z)
    {
	fprintf (gnuplot_comfile_ptr, "set view ,%g\n", RotZ);
    }
    if (LowFrequency != LOWEST_FREQUENCY &&
	HighFrequency != HIGHEST_FREQUENCY)
    {
	restrict_xrange = TRUE;
	xrange[0] = LowFrequency;
	xrange[1] = HighFrequency;
    }
    else if (LowFrequency != LOWEST_FREQUENCY)
    {
	restrict_xrange = TRUE;
	xrange[0] = LowFrequency;
    }
    else if (HighFrequency != HIGHEST_FREQUENCY)
    {
	restrict_xrange = TRUE;
	xrange[1] = HighFrequency;
    }
    if (this_is_re_plot && restrict_xrange)
    {
#ifdef _FFP
	fprintf (gnuplot_comfile_ptr, "set xrange [%-15.8g:%-15.8g]\n",
		 xrange[0], xrange[1]);
#else
	fprintf (gnuplot_comfile_ptr, "set xrange [%-19.12g:%-19.12g]\n",
		 xrange[0], xrange[1]);
#endif
    }

    write_plot_commands (gnuplot_comfile_ptr, NullString, NullString,
			 PlotCommands);

    if (Time3D)
    {
	fprintf (gnuplot_comfile_ptr, "set parametric\n");
	if (Hidden3D)
	{
	    fprintf (gnuplot_comfile_ptr, "set hidden3d\n");
	}


#ifdef GPLOT_3D_LOG_BUG_WORKAROUND
/*
 * This works around a bug in GNUPLOT 3.5 and below:
 * log x caused crash in 3d unless urange was set beforehand
 */
	if (LogX)
	{
	    fprintf (gnuplot_comfile_ptr,
"# The following line is a workaround for a bug in GNUPLOT 3.5\n");

	   fprintf (gnuplot_comfile_ptr, "set urange [1:2]\n");
	}
#endif

	fprintf (gnuplot_comfile_ptr, "splot ");
    }
    else
    {
	fprintf (gnuplot_comfile_ptr, "plot ");
    }
    if (CombinePlots)
    {
	int i;

	if (re_plotting && Old_File_Count)
	{
	    if (strlen (OkWriteName) ==
		strlen (Old_File_Name[Old_File_Count - 1]))
	    {
		if (!strcmp(OkWriteName,Old_File_Name[Old_File_Count - 1]))
		{
		    Old_File_Count--;
		}
	    }
	}

	for (i = 0; i < Old_File_Count; i++)
	{
	    fprintf (gnuplot_comfile_ptr, "\'%s\' with lines,",
		     Old_File_Name[i]);
	}
    }
    fprintf (gnuplot_comfile_ptr, "\'%s\' with lines\n",OkWriteName);
    fclose (gnuplot_comfile_ptr);

    save_name = gmalloc (strlen(OkWriteName) + 1, NOTHING_SPECIAL);
    strcpy (save_name, OkWriteName);
    Old_File_Count = (CombinePlots) ? ++Old_File_Count : 1;

    Old_File_Name = grealloc (Old_File_Name, Old_File_Count *
			      sizeof (char *), NOTHING_SPECIAL);
    Old_File_Name[Old_File_Count-1] = save_name;


/**************************************************************************\
 * Write shell command
\**************************************************************************/

#ifdef AMIGA
    sprintf (buffer,
	     "newcli CON:0/0/%d/%d/Gfft-Gnuplot-Shell from %s", 
	     Shell_Width, Shell_Height, plot_command_file_name);
#else
    sprintf (buffer, "%s", plot_command_file_name);
#endif

/**************************************************************************\
 * Execute shell command
\**************************************************************************/

    system (buffer);
}
[ RETURN TO DIRECTORY ]