/[ascend]/trunk/base/generic/compiler/plot.c
ViewVC logotype

Contents of /trunk/base/generic/compiler/plot.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 188 - (show annotations) (download) (as text)
Mon Jan 16 07:47:02 2006 UTC (18 years, 6 months ago) by johnpye
File MIME type: text/x-csrc
File size: 11203 byte(s)
Adding some missing 'EXT' code, adding 'error_reporter_here' functionality.
1 /*
2 * General Plot Functions
3 * Interface pointer functions for Ascend
4 * Version: $Revision: 1.4 $
5 * Version control file: $RCSfile: plot.c,v $
6 * Date last modified: $Date: 1998/02/18 21:11:53 $
7 * Last modified by: $Author: ballan $
8 * Part of Ascend
9 *
10 * This file is part of the Ascend Programming System.
11 *
12 * Copyright (C) 1990 Thomas Guthrie Epperly, Karl Michael Westerberg
13 * Copyright (C) 1994 Kirk Andre Abbott, Benjamin Andrew Allan
14 *
15 * The Ascend Programming System is free software; you can redistribute
16 * it and/or modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of the
18 * License, or (at your option) any later version.
19 *
20 * ASCEND is distributed in hope that it will be
21 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with the program; if not, write to the Free Software Foundation,
27 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
28 * COPYING.
29 *
30 * This module defines the plot generation auxillaries for Ascend.
31 *
32 */
33
34 #include "utilities/ascConfig.h"
35 #include "utilities/error.h"
36 #include "general/list.h"
37 #include "compiler/instance_enum.h"
38 #include "compiler/fractions.h"
39 #include "compiler/compiler.h"
40 #include "compiler/symtab.h"
41 #include "compiler/dimen.h"
42 #include "compiler/atomvalue.h"
43 #include "compiler/instance_name.h"
44 #include "compiler/parentchild.h"
45 #include "compiler/instquery.h"
46 #include "compiler/child.h"
47 #include "compiler/type_desc.h"
48 #include "compiler/module.h"
49 #include "compiler/library.h"
50 #include "compiler/plot.h"
51
52 /*
53 * ASSUMPTION ASSUMPTION ASSUMPTION:
54 * The points are to be displayed in the order that ASCEND
55 * internally sorts arrays, i.e. increasing integer subscript value.
56 *
57 * By making these assumptions, we remove the strict requirement
58 * that the curves have points indexed 1..n. We might, after all,
59 * want to index from 0.
60 */
61 enum PlotTypes g_plot_type;
62
63 static symchar *g_strings[16];
64 #define PLOT_POINT_SYM g_strings[0]
65 #define PLOT_POINT_INT g_strings[1]
66 #define PLOT_TITLE g_strings[2]
67 #define PLOT_XLABEL g_strings[3]
68 #define PLOT_YLABEL g_strings[4]
69 #define PLOT_XLOG g_strings[5]
70 #define PLOT_YLOG g_strings[6]
71 #define PLOT_XLO g_strings[7]
72 #define PLOT_YLO g_strings[8]
73 #define PLOT_XHI g_strings[9]
74 #define PLOT_YHI g_strings[10]
75 #define PLOT_CURVE g_strings[11]
76 #define PLOT_LEGEND g_strings[12]
77 #define PLOT_POINT g_strings[13]
78 #define PLOT_XPOINT g_strings[14]
79 #define PLOT_YPOINT g_strings[15]
80
81 static void init_gstrings(void)
82 {
83 PLOT_POINT_SYM = AddSymbol("plt_plot_symbol");
84 PLOT_POINT_INT = AddSymbol("plt_plot_integer");
85 PLOT_TITLE = AddSymbolL("title",5);
86 PLOT_XLABEL = AddSymbolL("XLabel",6);
87 PLOT_YLABEL = AddSymbolL("YLabel",6);
88 PLOT_XLOG = AddSymbolL("Xlog",4);
89 PLOT_YLOG = AddSymbolL("Ylog",4);
90 PLOT_XLO = AddSymbolL("Xlow",4);
91 PLOT_YLO = AddSymbolL("Ylow",4);
92 PLOT_XHI = AddSymbolL("Xhigh",5);
93 PLOT_YHI = AddSymbolL("Yhigh",5);
94 PLOT_CURVE = AddSymbolL("curve",5);
95 PLOT_LEGEND = AddSymbolL("legend",6);
96 PLOT_POINT = AddSymbolL("pnt",3);
97 PLOT_XPOINT = AddSymbolL("x",1);
98 PLOT_YPOINT = AddSymbolL("y",1);
99 }
100
101 /*
102 * returns TRUE if the type of inst is more refined than the type of
103 * plt_point_int or plt_point_sym
104 */
105 boolean plot_allowed(struct Instance *inst) {
106 struct TypeDescription *type, *plt_type_s, *plt_type_i;
107 if (inst==NULL) {
108 error_reporter(ASC_PROG_WARNING,__FILE__,__LINE__,"Instance is null");
109 return 0;
110 }
111
112 init_gstrings(); /* set up symchars for the child queries */
113 plt_type_s = FindType(PLOT_POINT_SYM); /* look for plt_point_sym */
114 plt_type_i = FindType(PLOT_POINT_INT); /* look for plt_point_int */
115 if (plt_type_i == NULL && plt_type_s == NULL) {
116 /* CONSOLE_DEBUG("No plottable types are present in the library"); */
117 return 0; /* no plots => fail */
118 }
119 type = InstanceTypeDesc(inst);
120 if (type==NULL) {
121 CONSOLE_DEBUG("type is NULL");
122 return 0; /* atom children have not type */
123 }
124 /* type is more refined than symbol plot */
125 if ((plt_type_s && type == MoreRefined(type,plt_type_s))||
126 (plt_type_i && type == MoreRefined(type,plt_type_i))) {
127 return 1;
128 }
129 return 0;
130 }
131
132
133 /*
134 * A very similar function such as the one below is defined in BrowserProc.c.
135 * We need to do some reorganization. kaa.
136 */
137 static unsigned long ChildNumberbyChar(struct Instance *i, symchar *name)
138 {
139 struct InstanceName rec;
140 unsigned long c = 0;
141 unsigned long nch = 0;
142 long index;
143
144 if(i==NULL||name==NULL) {
145 FPRINTF(stderr,"Null Instance or name in ChildbyNameChar\n");
146 return 0;
147 }
148 assert(AscFindSymbol(name)!=NULL);
149 nch = NumberChildren(i);
150 if(!nch) return 0;
151 do {
152 c++;
153 rec = ChildName(i,c);
154 switch (InstanceNameType(rec)){
155 case StrName:
156 if (InstanceNameStr(rec) == name) {
157 return c;
158 }
159 break;
160 case IntArrayIndex:
161 index = atol(SCP(name));
162 if (index==InstanceIntIndex(rec)) {
163 return c;
164 }
165 break;
166 case StrArrayIndex:
167 if (InstanceStrIndex(rec) == name) {
168 return c;
169 }
170 break;
171 }
172 } while(c < nch);
173 return 0; /*NOTREACHED*/
174 }
175
176 static
177 void do_plot_legends(FILE *fp, struct Instance *i, symchar *label)
178 {
179 struct Instance *str_inst;
180 unsigned long ndx;
181 ndx = ChildNumberbyChar(i,label);
182 if (ndx) {
183 str_inst = InstanceChild(i,ndx);
184 if (AtomAssigned(str_inst)) {
185 switch(g_plot_type) {
186 case PLAIN_PLOT:
187 FPRINTF(fp,"\n\n");
188 break;
189 case GNU_PLOT:
190 FPRINTF(fp,"\n#\"%s\"\n",SCP(GetSymbolAtomValue(str_inst)));
191 break;
192 case XGRAPH_PLOT:
193 FPRINTF(fp,"\n\"%s\n",SCP(GetSymbolAtomValue(str_inst)));
194 break;
195 default:
196 break;
197 }
198 } else {
199 FPRINTF(fp,"\n\n");
200 }
201 }
202 }
203
204 static
205 void do_plot_labels(FILE *fp, struct Instance *i, symchar *label,
206 char *labelstring)
207 {
208 struct Instance *inst;
209 unsigned long ndx;
210 assert(AscFindSymbol(label)!=NULL);
211 ndx = ChildNumberbyChar(i,label);
212 if (ndx) {
213 inst = InstanceChild(i,ndx);
214 if (AtomAssigned(inst)) {
215 switch (InstanceKind(inst)) {
216 case REAL_INST:
217 case REAL_ATOM_INST:
218 case REAL_CONSTANT_INST:
219 FPRINTF(fp,"%s %.18g\n",labelstring, RealAtomValue(inst));
220 break;
221 case INTEGER_INST:
222 case INTEGER_ATOM_INST:
223 case INTEGER_CONSTANT_INST:
224 FPRINTF(fp,"%s %ld\n",labelstring, GetIntegerAtomValue(inst));
225 break;
226 case SYMBOL_INST:
227 case SYMBOL_ATOM_INST:
228 case SYMBOL_CONSTANT_INST:
229 FPRINTF(fp,"%s %s\n",labelstring, SCP(GetSymbolAtomValue(inst)));
230 break;
231 case BOOLEAN_INST:
232 case BOOLEAN_ATOM_INST:
233 case BOOLEAN_CONSTANT_INST:
234 FPRINTF(fp,"%s %d\n",labelstring,
235 (GetBooleanAtomValue(inst)!=0)?1:0);
236 break;
237 default:
238 break;
239 }
240 }
241 }
242 }
243
244 /**
245 Plot point and option connecting line, providing values of point are well defined.
246
247 @param point location of new coordinate pair
248 @param drawline should a line be draw from the current location to the new point?
249 @param fp file to which plot commands are output
250 */
251 static void write_point(FILE *fp, struct Instance *point, boolean drawline)
252 {
253 /* ? draw line from previous point
254 * Writes a given point (instance of plt_point) to fp
255 * if values of point are well defined.
256 */
257 unsigned long ndx;
258 struct Instance *ix, *iy;
259 double x,y;
260
261 ndx = ChildNumberbyChar(point,PLOT_XPOINT); /* do x */
262 ix = InstanceChild(point,ndx);
263 ndx = ChildNumberbyChar(point,PLOT_YPOINT); /* do y */
264 iy = InstanceChild(point,ndx);
265
266 if (ix != NULL && iy != NULL && AtomAssigned(ix) && AtomAssigned(iy)) {
267 x = RealAtomValue(ix);
268 y = RealAtomValue(iy);
269 FPRINTF(fp,drawline ? "%g %g\n" : "move %g %g\n",x,y);
270 }
271 }
272
273 /**
274 Writes the specified curve to the file.
275
276 @param fp file to which output is made
277 @param curve instance containing the curve required
278 @param curve_number disused
279 */
280 static void write_curve(FILE *fp,
281 struct Instance *curve,
282 unsigned long curve_number)
283 {
284
285 struct Instance *point_array_inst, *a_point;
286 unsigned long ndx;
287 unsigned long npoints;
288 unsigned long c;
289
290 (void)curve_number; /* stopping gcc whine about unused parameter */
291
292 /* do plot legend */
293 do_plot_legends(fp,curve,PLOT_LEGEND);
294
295 ndx = ChildNumberbyChar(curve,PLOT_POINT);
296 if (ndx) {
297 point_array_inst = InstanceChild(curve,ndx);
298 npoints = NumberChildren(point_array_inst);
299 for (c=1;c<=npoints;c++) {
300 a_point = InstanceChild(point_array_inst,c);
301 write_point(fp,a_point,1);
302 }
303 }
304 }
305
306 /*
307 Write plotting instructions for plot_inst to the specified plotfilename.
308 */
309 void plot_prepare_file(struct Instance *plot_inst, char *plotfilename)
310 {
311 struct Instance *curve_array_inst, *a_curve;
312 unsigned long ndx;
313 unsigned long ncurves;
314 unsigned long c;
315 enum inst_t kind;
316 FILE *fp;
317
318 if (plot_inst==NULL) {
319 return;
320 }
321 fp=fopen(plotfilename,"w");
322 if( fp == NULL ) {
323 FPRINTF(stderr,"ERROR: plot_prepare_file: Cannot open %s for writing.\n",
324 plotfilename);
325 return;
326 }
327 init_gstrings(); /* set up symchars for the child queries */
328 /* do the plot labels */
329 switch(g_plot_type) {
330 case PLAIN_PLOT:
331 break;
332 case GNU_PLOT:
333 FPRINTF(fp,"#Plot data for gnuplot generated by ASCEND\n");
334 FPRINTF(fp,"#Remove # marks for legends etc.\n\n");
335 do_plot_labels(fp,plot_inst,PLOT_TITLE, "#set title ");
336 do_plot_labels(fp,plot_inst,PLOT_XLABEL, "#set xlabel ");
337 do_plot_labels(fp,plot_inst,PLOT_YLABEL, "#set ylabel ");
338 break;
339 case XGRAPH_PLOT:
340 FPRINTF(fp,"#Plot data for Xgraph generated by ASCEND\n\n");
341 do_plot_labels(fp,plot_inst,PLOT_TITLE, "TitleText: ");
342 do_plot_labels(fp,plot_inst,PLOT_XLABEL, "XUnitText: ");
343 do_plot_labels(fp,plot_inst,PLOT_YLABEL, "YUnitText: ");
344 do_plot_labels(fp,plot_inst,PLOT_YLOG, "LogY: ");
345 do_plot_labels(fp,plot_inst,PLOT_XLOG, "LogX: ");
346 do_plot_labels(fp,plot_inst,PLOT_YLO, "YLowLimit: ");
347 do_plot_labels(fp,plot_inst,PLOT_XLO, "XLowLimit: ");
348 do_plot_labels(fp,plot_inst,PLOT_YHI, "YHighLimit: ");
349 do_plot_labels(fp,plot_inst,PLOT_XHI, "XHighLimit: ");
350 break;
351 default:
352 break;
353 }
354
355 ndx = ChildNumberbyChar(plot_inst,PLOT_CURVE); /*search for curve_array*/
356 if (ndx) {
357 curve_array_inst = InstanceChild(plot_inst,ndx);
358 kind = InstanceKind(curve_array_inst);
359 ncurves = NumberChildren(curve_array_inst); /*get no. of curves*/
360 for (c=1;c<=ncurves;c++) { /*get true curve number*/
361 if (kind==ARRAY_INT_INST || kind==ARRAY_ENUM_INST) {
362 a_curve = InstanceChild(curve_array_inst,c);
363 write_curve(fp,a_curve,c);
364 }
365 }
366 }
367 fclose(fp);
368 }

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22