/*************************************************************************** * 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 #include #include #ifdef AMIGA #include #include #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 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); }