do interpolation when annotating "b" cursor values in schematic, as done with measurements with "a" cursor.
This commit is contained in:
parent
f87ab46310
commit
a7bcfb7941
|
|
@ -266,6 +266,8 @@ static void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr)
|
|||
dbg(1, "xx=%g, p=%d\n", xx, p);
|
||||
tcleval("array unset ngspice::ngspice_data");
|
||||
raw->annot_p = p;
|
||||
raw->annot_x = cursor2;
|
||||
raw->annot_sweep_idx = sweep_idx;
|
||||
for(i = 0; i < raw->nvars; ++i) {
|
||||
char s[100];
|
||||
my_snprintf(s, S(s), "%.4g", raw->values[i][p]);
|
||||
|
|
@ -403,6 +405,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
}
|
||||
} else {
|
||||
xctx->raw->annot_p = -1;
|
||||
xctx->raw->annot_sweep_idx = -1;
|
||||
/* need_all_redraw = 1; */
|
||||
redraw_all_at_end = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -383,18 +383,16 @@ void transpose_matrix(double *a, int r, int c)
|
|||
* data layout in memory arranged to maximize cache locality
|
||||
* when looking up data
|
||||
*/
|
||||
static void read_binary_block(FILE *fd, Raw *raw)
|
||||
static void read_binary_block(FILE *fd, Raw *raw, int ac)
|
||||
{
|
||||
int p, v;
|
||||
double *tmp;
|
||||
int offset = 0;
|
||||
int ac = 0;
|
||||
|
||||
if(!raw) {
|
||||
dbg(0, "read_binary_block() no raw struct allocated\n");
|
||||
return;
|
||||
}
|
||||
if(!strcmp(raw->sim_type, "ac")) ac = 1; /* AC analysis, complex numbers twice the size */
|
||||
|
||||
for(p = 0 ; p < raw->datasets; p++) {
|
||||
offset += raw->npoints[p];
|
||||
|
|
@ -497,7 +495,7 @@ static int read_dataset(FILE *fd, Raw **rawptr, const char *type)
|
|||
if(raw->sim_type) {
|
||||
done_header = 1;
|
||||
dbg(dbglev, "read_dataset(): read binary block, nvars=%d npoints=%d\n", nvars, npoints);
|
||||
read_binary_block(fd, raw);
|
||||
read_binary_block(fd, raw, ac);
|
||||
raw->datasets++;
|
||||
exit_status = 1;
|
||||
} else {
|
||||
|
|
@ -775,6 +773,7 @@ int raw_read(const char *f, Raw **rawptr, const char *type)
|
|||
raw = *rawptr;
|
||||
raw->level = -1;
|
||||
raw->annot_p = -1;
|
||||
raw->annot_sweep_idx = -1;
|
||||
|
||||
int_hash_init(&raw->table, HASHSIZE);
|
||||
fd = fopen(f, fopen_read_mode);
|
||||
|
|
@ -842,6 +841,7 @@ int table_read(const char *f)
|
|||
raw = xctx->raw;
|
||||
raw->level = -1;
|
||||
raw->annot_p = -1;
|
||||
raw->annot_sweep_idx = -1;
|
||||
|
||||
/* quick inspect file and get upper bound of number of data lines */
|
||||
ufd = open(f, O_RDONLY);
|
||||
|
|
|
|||
41
src/token.c
41
src/token.c
|
|
@ -3380,6 +3380,31 @@ static char *get_pin_attr(const char *token, int inst, int s_pnetname)
|
|||
return value;
|
||||
}
|
||||
|
||||
static double interpolate_yval(int idx)
|
||||
{
|
||||
double val = xctx->raw->values[idx][xctx->raw->annot_p];
|
||||
/* not operating point, annotate from 'b' cursor */
|
||||
if((xctx->raw->allpoints > 1) && xctx->raw->annot_sweep_idx >= 0) {
|
||||
Raw *raw = xctx->raw;
|
||||
int dset;
|
||||
int npoints;
|
||||
SPICE_DATA *sweep_gv = raw->values[raw->annot_sweep_idx];
|
||||
SPICE_DATA *gv = raw->values[idx];
|
||||
for(dset = 0 ; dset < raw->datasets; dset++) {
|
||||
npoints += raw->npoints[dset];
|
||||
if(npoints > raw->annot_p) break;
|
||||
}
|
||||
if(raw->annot_p + 1 < npoints) {
|
||||
double dx = sweep_gv[raw->annot_p + 1] - sweep_gv[raw->annot_p];
|
||||
double dy = gv[raw->annot_p + 1] - gv[raw->annot_p];
|
||||
double offset = raw->annot_x - sweep_gv[raw->annot_p];
|
||||
double interp = dx != 0.0 ? offset * dy / dx : 0.0;
|
||||
val += interp;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/* substitute given tokens in a string with their corresponding values */
|
||||
/* ex.: name=@name w=@w l=@l ---> name=m112 w=3e-6 l=0.8e-6 */
|
||||
/* if s==NULL return emty string */
|
||||
|
|
@ -3599,7 +3624,7 @@ const char *translate(int inst, const char* s)
|
|||
dbg(1, "translate() @spice_get_voltage: fqnet=%s start_level=%d\n", fqnet, start_level);
|
||||
idx = get_raw_index(fqnet);
|
||||
if(idx >= 0) {
|
||||
val = xctx->raw->values[idx][xctx->raw->annot_p];
|
||||
val = interpolate_yval(idx);
|
||||
}
|
||||
if(idx < 0) {
|
||||
valstr = "";
|
||||
|
|
@ -3656,7 +3681,7 @@ const char *translate(int inst, const char* s)
|
|||
dbg(1, "translate(): net=%s, fqnet=%s start_level=%d\n", net, fqnet, start_level);
|
||||
idx = get_raw_index(fqnet);
|
||||
if(idx >= 0) {
|
||||
val = xctx->raw->values[idx][xctx->raw->annot_p];
|
||||
val = interpolate_yval(idx);
|
||||
}
|
||||
if(idx < 0) {
|
||||
valstr = "";
|
||||
|
|
@ -3724,7 +3749,7 @@ const char *translate(int inst, const char* s)
|
|||
dbg(1, "fqdev=%s\n", fqdev);
|
||||
idx = get_raw_index(fqdev);
|
||||
if(idx >= 0) {
|
||||
val = xctx->raw->values[idx][xctx->raw->annot_p];
|
||||
val = interpolate_yval(idx);
|
||||
}
|
||||
if(idx < 0) {
|
||||
valstr = "";
|
||||
|
|
@ -3784,19 +3809,13 @@ const char *translate(int inst, const char* s)
|
|||
dbg(1, "translate(): fqnet1=%s start_level=%d\n", fqnet1, start_level);
|
||||
dbg(1, "translate(): fqnet2=%s start_level=%d\n", fqnet2, start_level);
|
||||
idx1 = get_raw_index(fqnet1);
|
||||
if(idx1 >= 0) {
|
||||
val1 = xctx->raw->values[idx1][xctx->raw->annot_p];
|
||||
}
|
||||
idx2 = get_raw_index(fqnet2);
|
||||
if(idx2 >= 0) {
|
||||
val2 = xctx->raw->values[idx2][xctx->raw->annot_p];
|
||||
}
|
||||
val = val1 - val2;
|
||||
if(idx1 < 0 || idx2 < 0) {
|
||||
valstr = "";
|
||||
xctx->tok_size = 0;
|
||||
len = 0;
|
||||
} else {
|
||||
val = interpolate_yval(idx1) - interpolate_yval(idx2);
|
||||
valstr = dtoa_eng(val);
|
||||
len = xctx->tok_size;
|
||||
}
|
||||
|
|
@ -3856,7 +3875,7 @@ const char *translate(int inst, const char* s)
|
|||
strtolower(fqdev);
|
||||
idx = get_raw_index(fqdev);
|
||||
if(idx >= 0) {
|
||||
val = xctx->raw->values[idx][xctx->raw->annot_p];
|
||||
val = interpolate_yval(idx);
|
||||
}
|
||||
if(idx < 0) {
|
||||
valstr = "";
|
||||
|
|
|
|||
|
|
@ -774,7 +774,12 @@ typedef struct {
|
|||
int datasets;
|
||||
Int_hashtable table;
|
||||
const char *sim_type; /* type of sim, "tran", "dc", "ac", "op", ... */
|
||||
int annot_p; /* point in raw file to use for annotating schematic voltages/currents/etc */
|
||||
int annot_p; /* point in raw file to use for annotating schematic voltages/currents/etc
|
||||
* this is the closest available simulated point *before* the point
|
||||
* calculated from mouse in graph */
|
||||
double annot_x; /* X point to backannotate as calculated from mouse position.
|
||||
* need to interpolate the Y value between annot_p and annot_p + 1 */
|
||||
int annot_sweep_idx; /* index of sweep variable where cursor annotation has occurred */
|
||||
/* when descending hierarchy xctx->current_name changes, xctx->raw_schname
|
||||
* holds the name of the top schematic from which the raw file was loaded */
|
||||
char *schname;
|
||||
|
|
|
|||
Loading…
Reference in New Issue