diff --git a/src/draw.c b/src/draw.c index bfc78d86..f89a4f11 100644 --- a/src/draw.c +++ b/src/draw.c @@ -3147,7 +3147,7 @@ int calc_custom_data_yrange(int sweep_idx, const char *express, Graph_ctx *gr) if(xx > end || xx < start || /* ... and we ran out of graph area ... */ wrap) { /* ... or sweep variable changed direction */ if(dataset == -1 || dataset == sweepvar_wrap) { - idx = plot_raw_custom_data(sweep_idx, first, last, express); + idx = plot_raw_custom_data(sweep_idx, first, last, express, NULL); } first = -1; } @@ -3164,7 +3164,7 @@ int calc_custom_data_yrange(int sweep_idx, const char *express, Graph_ctx *gr) } /* for(p = ofs ; p < ofs + raw->npoints[dset]; p++) */ if(first != -1) { if(dataset == -1 || dataset == sweepvar_wrap) { - idx = plot_raw_custom_data(sweep_idx, first, last, express); + idx = plot_raw_custom_data(sweep_idx, first, last, express, NULL); } } /* offset pointing to next dataset */ @@ -3258,7 +3258,7 @@ int find_closest_wave(int i, Graph_ctx *gr) register SPICE_DATA *gvx = raw->values[sweep_idx]; register SPICE_DATA *gvy; ofs_end = ofs + raw->npoints[dset]; - if(expression) plot_raw_custom_data(sweep_idx, ofs, ofs_end - 1, express); + if(expression) plot_raw_custom_data(sweep_idx, ofs, ofs_end - 1, express, NULL); gvy = raw->values[idx]; dbg(1, "find_closest_wave(): dset=%d\n", dset); first = -1; @@ -3551,7 +3551,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct) sweep_idx, wcnt, n_nodes, gr, ct); } } else { - if(expression) idx = plot_raw_custom_data(sweep_idx, first, last, express); + if(expression) idx = plot_raw_custom_data(sweep_idx, first, last, express, NULL); draw_graph_points(idx, first, last, point, wave_color, wcnt, n_nodes, gr, ct); } } @@ -3594,7 +3594,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct) sweep_idx, wcnt, n_nodes, gr, ct); } } else { - if(expression) idx = plot_raw_custom_data(sweep_idx, first, last, express); + if(expression) idx = plot_raw_custom_data(sweep_idx, first, last, express, NULL); draw_graph_points(idx, first, last, point, wave_color, wcnt, n_nodes, gr, ct); } } diff --git a/src/save.c b/src/save.c index 1af1db32..ded369ec 100644 --- a/src/save.c +++ b/src/save.c @@ -824,30 +824,34 @@ int raw_read_from_attr(Raw **rawptr, const char *type, double sweep1, double swe return res; } -int raw_add_vector(const char *varname) +int raw_add_vector(const char *varname, const char *expr) { int f; + int res = 0; Raw *raw = xctx->raw; if(!raw || !raw->values) return 0; - if(int_hash_lookup(&raw->table, varname, 0, XLOOKUP)) { - return 0; + if(!int_hash_lookup(&raw->table, varname, 0, XLOOKUP)) { + raw->nvars++; + my_realloc(_ALLOC_ID_, &raw->names, raw->nvars * sizeof(char *)); + my_realloc(_ALLOC_ID_, &raw->cursor_b_val, raw->nvars * sizeof(double)); + raw->cursor_b_val[raw->nvars - 1] = 0.0; + raw->names[raw->nvars - 1] = NULL; + my_strdup2(_ALLOC_ID_, &raw->names[raw->nvars - 1], varname); + int_hash_lookup(&raw->table, raw->names[raw->nvars - 1], raw->nvars - 1, XINSERT_NOREPLACE); + my_realloc(_ALLOC_ID_, &raw->values, (raw->nvars + 1) * sizeof(SPICE_DATA *)); + raw->values[raw->nvars] = NULL; + my_realloc(_ALLOC_ID_, &raw->values[raw->nvars], raw->allpoints * sizeof(SPICE_DATA)); + res = 1; } - raw->nvars++; - my_realloc(_ALLOC_ID_, &raw->names, raw->nvars * sizeof(char *)); - my_realloc(_ALLOC_ID_, &raw->cursor_b_val, raw->nvars * sizeof(double)); - raw->cursor_b_val[raw->nvars - 1] = 0.0; - raw->names[raw->nvars - 1] = NULL; - my_strdup2(_ALLOC_ID_, &raw->names[raw->nvars - 1], varname); - int_hash_lookup(&raw->table, raw->names[raw->nvars - 1], raw->nvars - 1, XINSERT_NOREPLACE); - - my_realloc(_ALLOC_ID_, &raw->values, (raw->nvars + 1) * sizeof(SPICE_DATA *)); - raw->values[raw->nvars] = NULL; - my_realloc(_ALLOC_ID_, &raw->values[raw->nvars], raw->allpoints * sizeof(SPICE_DATA)); - for(f = 0; f < raw->allpoints; f++) { - raw->values[raw->nvars - 1][f] = 0.0; + if(expr) { + plot_raw_custom_data(0, 0, raw->allpoints, expr, varname); + } else if(res == 1) { + for(f = 0; f < raw->allpoints; f++) { + raw->values[raw->nvars - 1][f] = 0.0; + } } - return 1; + return res; } /* read a ngspice raw file (with data portion in binary format) */ @@ -1459,7 +1463,7 @@ typedef struct { int prevp; } Stack1; -int plot_raw_custom_data(int sweep_idx, int first, int last, const char *expr) +int plot_raw_custom_data(int sweep_idx, int first, int last, const char *expr, const char *yname) { int i, p, idx; const char *n; @@ -1467,10 +1471,17 @@ int plot_raw_custom_data(int sweep_idx, int first, int last, const char *expr) Stack1 stack1[STACKMAX]; double stack2[STACKMAX]={0}, tmp, result, avg; int stackptr1 = 0, stackptr2 = 0; - SPICE_DATA *y = xctx->raw->values[xctx->raw->nvars]; /* custom plot data column */ + SPICE_DATA *y; SPICE_DATA *x = xctx->raw->values[sweep_idx]; SPICE_DATA *sweepx = xctx->raw->values[0]; + y = xctx->raw->values[xctx->raw->nvars]; /* custom plot data column */ + if(yname != NULL) { + int yidx = get_raw_index(yname); + if(yidx >= 0) { + y = xctx->raw->values[yidx]; /* provided index */ + } + } my_strdup2(_ALLOC_ID_, &ntok_copy, expr); ntok_ptr = ntok_copy; dbg(1, "plot_raw_custom_data(): expr=%s\n", expr); diff --git a/src/scheduler.c b/src/scheduler.c index 8b3feb86..85fb2faf 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -3502,7 +3502,11 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg * xschem raw_query points [dset]: print simulation points for * dataset 'dset' (default: all dataset points combined) * xschem raw_query set node n value [dataset]: change loaded raw file data node[n] to value - * xschem raw_query add varname: add a 'varname' vector with all values set to 0 to loaded raw file + * xschem raw_query add varname [expr] + * add a 'varname' vector with all values set to 0 to loaded raw file if expr not given + * otherwise initialize data with values calculated from expr. + * If varname is already existing and expr given recalculate data + * Example: xschem raw_query add power {outm outp - i(@r1[i]) *} * */ else if(!strcmp(argv[1], "raw_query")) @@ -3560,7 +3564,11 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg } } else if(argc > 3 && !strcmp(argv[2], "add")) { int res = 0; - res = raw_add_vector(argv[3]); + if(argc > 4) { + res = raw_add_vector(argv[3], argv[4]); + } else { + res = raw_add_vector(argv[3], NULL); + } Tcl_SetResult(interp, my_itoa(res), TCL_VOLATILE); } else if(argc > 2 && !strcmp(argv[2], "datasets")) { Tcl_SetResult(interp, my_itoa(raw->datasets), TCL_VOLATILE); diff --git a/src/xschem.h b/src/xschem.h index c43eca14..75523d62 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1223,7 +1223,7 @@ extern int filter_data(const char *din, const size_t ilen, extern int embed_rawfile(const char *rawfile); extern int read_rawfile_from_attr(const char *b64s, size_t length, const char *type); extern int raw_read_from_attr(Raw **rawptr, const char *type, double sweep1, double sweep2); -extern int raw_add_vector(const char *varname); +extern int raw_add_vector(const char *varname, const char *expr); extern int new_rawfile(const char *name, const char *type, const char *sweepvar, double start, double step, int number); extern char *base64_from_file(const char *f, size_t *length); @@ -1244,7 +1244,7 @@ extern int extra_rawfile(int what, const char *f, const char *type, double sweep extern int raw_read(const char *f, Raw **rawptr, const char *type, double sweep1, double sweep2); extern int table_read(const char *f); extern double get_raw_value(int dataset, int idx, int point); -extern int plot_raw_custom_data(int sweep_idx, int first, int last, const char *ntok); +extern int plot_raw_custom_data(int sweep_idx, int first, int last, const char *ntok, const char *yname); extern int calc_custom_data_yrange(int sweep_idx, const char *express, Graph_ctx *gr); extern int sch_waves_loaded(void); extern int edit_wave_attributes(int what, int i, Graph_ctx *gr);