From ac3f3acb620f4782c7e42e5672061de29d509db2 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Fri, 23 Feb 2024 01:03:20 +0100 Subject: [PATCH] added command `xschem raw new name type sweepvar start step number` that creates an in-memory plot (like a loaded raw file) with only the sweep variable --- src/editprop.c | 2 +- src/save.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++- src/scheduler.c | 17 ++++++++---- src/xschem.h | 2 ++ 4 files changed, 86 insertions(+), 8 deletions(-) diff --git a/src/editprop.c b/src/editprop.c index 3d2b2d5d..33d110fb 100644 --- a/src/editprop.c +++ b/src/editprop.c @@ -489,7 +489,7 @@ char *dtoa(double i) static char s[70]; size_t n; - n = my_snprintf(s, S(s), "%g", i); + n = my_snprintf(s, S(s), "%.8g", i); if(xctx) xctx->tok_size = n; return s; } diff --git a/src/save.c b/src/save.c index ad42de00..597c683b 100644 --- a/src/save.c +++ b/src/save.c @@ -842,7 +842,6 @@ int raw_add_vector(const char *varname) for(f = 0; f < raw->allpoints; f++) { raw->values[raw->nvars - 1][f] = 0.0; } - return 1; } @@ -906,6 +905,78 @@ int raw_read(const char *f, Raw **rawptr, const char *type, double sweep1, doubl return 0; } +/* create a new raw file with 'number' points with only a sweep variable in it. */ +int new_rawfile(const char *name, const char *type, const char *sweepvar, + double start, double step, int number) +{ + int i; + int ret = 1; + Raw *raw; + + /* if not already done insert base raw file (if there is one) into xctx->extra_raw_arr[0] */ + if(xctx->raw && xctx->extra_raw_n == 0) { + xctx->extra_raw_arr[xctx->extra_raw_n] = xctx->raw; + xctx->extra_raw_n++; + } + + if(xctx->extra_raw_n < MAX_RAW_N && name && type) { + for(i = 0; i < xctx->extra_raw_n; i++) { + if(xctx->extra_raw_arr[i]->sim_type && + !strcmp(xctx->extra_raw_arr[i]->rawfile, name) && + !strcmp(xctx->extra_raw_arr[i]->sim_type, type) + ) break; + } + + for(i = 0; i < xctx->extra_raw_n; i++) { + if( !strcmp(xctx->extra_raw_arr[i]->rawfile, name)) break; + } + if(i >= xctx->extra_raw_n) { /* file not already loaded: read it and switch to it */ + double t; + + xctx->raw = my_calloc(_ALLOC_ID_, 1, sizeof(Raw)); + raw = xctx->raw; + raw->level = -1; + raw->sweep1 = -1.0; + raw->sweep2 = -1.0; + raw->annot_p = -1; + raw->annot_sweep_idx = -1; + + int_hash_init(&raw->table, HASHSIZE); + my_strdup2(_ALLOC_ID_, &raw->rawfile, name); + my_strdup2(_ALLOC_ID_, &raw->schname, xctx->sch[xctx->currsch]); + my_strdup(_ALLOC_ID_, &raw->sim_type, type); + raw->level = xctx->currsch; + my_realloc(_ALLOC_ID_, &raw->npoints, 1 * sizeof(int)); /* for now assume only one dataset */ + raw->datasets = 1; + raw->allpoints = number; + raw->npoints[0] = number; + raw->nvars = 1; + raw->values = my_calloc(_ALLOC_ID_, raw->nvars + 1, sizeof(SPICE_DATA *)); + raw->values[0] = my_calloc(_ALLOC_ID_, number, sizeof(SPICE_DATA)); + raw->values[1] = my_calloc(_ALLOC_ID_, number, sizeof(SPICE_DATA)); + raw->names = my_calloc(_ALLOC_ID_, raw->nvars, sizeof(char *)); + my_strdup2(_ALLOC_ID_, &raw->names[0], sweepvar); + int_hash_lookup(&raw->table, raw->names[0], 0, XINSERT_NOREPLACE); + + for(i = 0; i < number; i++) { + t = start + i * step; + raw->values[0][i] = t; + } + + xctx->extra_raw_arr[xctx->extra_raw_n] = xctx->raw; + xctx->extra_prev_idx = xctx->extra_idx; + xctx->extra_idx = xctx->extra_raw_n; + xctx->extra_raw_n++; + } else { /* file found: print warning, do nothing */ + dbg(0, "new_rawfile(): the name: %s is already used. Choose a different name\n", name); + ret = 0; + } + } else { + ret = 0; + } + return ret; +} + /* what == 1: read another raw file and switch to it (make it the current one) * if type == table use table_read() to read an ascii table * what == 2: switch raw file. If filename given switch to that one, diff --git a/src/scheduler.c b/src/scheduler.c index c2a03aa4..8b3feb86 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -3418,10 +3418,13 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg break; case 'r': /*----------------------------------------------*/ /* raw what [rawfile type] [sweep1 sweep2] - * what = read | clear | info | switch | switch_back | table_read - * Load / clear / switch additional raw files - * if sweep1, sweep2 interval is given in 'read' subcommand load only the interval - * sweep1 <= sweep_var < sweep2 */ + * what = read | clear | info | switch | new | switch_back | table_read + * Load / clear / switch additional raw files + * if sweep1, sweep2 interval is given in 'read' subcommand load only the interval + * sweep1 <= sweep_var < sweep2 + * xschem raw new name type sweepvar start step number + * create a new raw file with sweep variable 'sweepvar' with number datapoints + * from start value 'start' and step 'step' */ if(!strcmp(argv[1], "raw")) { double sweep1 = -1.0, sweep2 = -1.0; @@ -3449,6 +3452,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg } update_op(); Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE); + } else if(argc > 8 && !strcmp(argv[2], "new")) { + ret = new_rawfile(argv[3], argv[4], argv[5], atof(argv[6]), atof(argv[7]),atoi(argv[8])); } else if(argc > 2 && !strcmp(argv[2], "info")) { ret = extra_rawfile(4, NULL, NULL, -1.0, -1.0); } else if(argc > 2 && !strcmp(argv[2], "switch_back")) { @@ -3480,7 +3485,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg Tcl_ResetResult(interp); } - /* raw_query loaded|value|index|values|datasets|vars|list|set|add + /* raw_query loaded | value | index | values | datasets | vars | list | set | add * xschem raw_query list: get list of saved simulation variables * xschem raw_query vars: get number of simulation variables * xschem raw_query datasets: get number of datasets (simulation runs) @@ -3549,7 +3554,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg np = raw->npoints[dataset]; Tcl_ResetResult(interp); for(p = 0; p < np; p++) { - sprintf(n, "%.10e", get_raw_value(dataset, idx, p)); + sprintf(n, "%.8g", get_raw_value(dataset, idx, p)); Tcl_AppendResult(interp, n, " ", NULL); } } diff --git a/src/xschem.h b/src/xschem.h index 3ef10234..c43eca14 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1224,6 +1224,8 @@ 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 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); extern int set_rect_flags(xRect *r); extern int set_text_flags(xText *t);