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

This commit is contained in:
stefan schippers 2024-02-23 01:03:20 +01:00
parent de5c068775
commit ac3f3acb62
4 changed files with 86 additions and 8 deletions

View File

@ -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;
}

View File

@ -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,

View File

@ -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);
}
}

View File

@ -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);