Cut out part of each vector of the current tran plot,

from times cut-tstart to cut-tstop and copy these
into a new tran plot. A new scale vector 'time' will be
generated as well. Vectors that are shorter than the
new scale vector will not be copied.
This commit is contained in:
Holger Vogt 2020-07-18 23:11:34 +02:00
parent 71338c3271
commit fe28feae4e
5 changed files with 198 additions and 1 deletions

View File

@ -597,6 +597,10 @@ struct comm spcp_coms[] = {
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS, { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
NULL, NULL,
" [ vec ... ] : Convert plot into one with linear scale." } , " [ vec ... ] : Convert plot into one with linear scale." } ,
{ "cutout", com_cutout, FALSE, FALSE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
NULL,
" [ vec ... ] : Cut out portion of a vector." },
{ "devhelp", com_devhelp, FALSE, FALSE, { "devhelp", com_devhelp, FALSE, FALSE,
{ 040000, 0400000, 040000, 040000 }, E_DEFHMASK, 0, 5 , { 040000, 0400000, 040000, 040000 }, E_DEFHMASK, 0, 5 ,
NULL, NULL,
@ -1005,6 +1009,10 @@ struct comm nutcp_coms[] = {
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS, { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
NULL, NULL,
" [ vec ... ] : Convert plot into one with linear scale." } , " [ vec ... ] : Convert plot into one with linear scale." } ,
{ "cutout", com_cutout, FALSE, FALSE,
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
NULL,
" [ vec ... ] : Cut out portion of a vector." },
{ "devhelp", NULL, FALSE, FALSE, { "devhelp", NULL, FALSE, FALSE,
{ 040, 040, 040, 040 }, E_DEFHMASK, 0, 5 , { 040, 040, 040, 040 }, E_DEFHMASK, 0, 5 ,
NULL, NULL,

View File

@ -20,7 +20,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
* Interpolation may be restricted to only a region of the input vector, * Interpolation may be restricted to only a region of the input vector,
* thus creating a cutout of the original vector. * thus creating a cutout of the original vector.
*/ */
void void
com_linearize(wordlist *wl) com_linearize(wordlist *wl)
{ {
@ -129,3 +128,128 @@ com_linearize(wordlist *wl)
} }
} }
} }
/* Cut out part of tran vectors from cut-tstart to cut-tstop and copy these
into a new plot. A new scale vector 'time' will be there as well. Vectors
that are shorter than the new scale vector will not be copied. */
void
com_cutout(wordlist* wl)
{
double tstart, tstop;
struct plot* new, * old;
struct dvec* newtime, * v, *nv;
struct dvec* oldtime;
struct dvec* sta, *sto;
int len, i, istart, istop;
if (!plot_cur || !plot_cur->pl_dvecs || !plot_cur->pl_scale) {
fprintf(cp_err, "Error: no vectors available\n");
return;
}
if (!isreal(plot_cur->pl_scale)) {
fprintf(cp_err, "Error: non-real time scale for %s\n",
plot_cur->pl_typename);
return;
}
if (!ciprefix("tran", plot_cur->pl_typename)) {
fprintf(cp_err, "Error: plot must be a transient analysis\n");
return;
}
int length = plot_cur->pl_scale->v_length;
if (length < 1) {
fprintf(cp_err, "Error: no data in vector\n");
return;
}
/* if this plot contains special vectors cut-tstart or cut-tstop, use these */
sta = vec_fromplot("cut-tstart", plot_cur);
if (sta) {
tstart = sta->v_realdata[0];
for (istart = 0; istart < length - 1; istart++) {
if (plot_cur->pl_scale->v_realdata[istart] > tstart) {
// istart--;
break;
}
}
}
else {
tstart = plot_cur->pl_scale->v_realdata[0];
istart = 0;
}
sto = vec_fromplot("cut-tstop", plot_cur);
/* return if neither start nor stop are given */
if (!sta && !sto)
return;
if (sto) {
tstop = sto->v_realdata[0];
for (istop = 0; istop < length - 1; istop++) {
if (plot_cur->pl_scale->v_realdata[istop] > tstop)
break;
}
}
else {
tstop = plot_cur->pl_scale->v_realdata[length - 1];
istop = length - 1;
}
/* finally check if tstart, tstop, istart and istop are reasonable */
if (((tstop - tstart) <= 0.0) || ((istop - istart) <= 0)) {
fprintf(cp_err,
"Error: bad parameters -- start = %G, stop = %G\n",
tstart, tstop);
return;
}
/* create a new plot */
old = plot_cur;
oldtime = old->pl_scale;
new = plot_alloc("transient");
new->pl_name = tprintf("%s (cut out)", old->pl_name);
new->pl_title = copy(old->pl_title);
new->pl_date = copy(old->pl_date);
new->pl_next = plot_list;
plot_new(new);
plot_setcur(new->pl_typename);
plot_list = new;
/* copy a new scale vector (time) */
len = istop - istart;
newtime = dvec_alloc(copy(oldtime->v_name),
oldtime->v_type,
oldtime->v_flags | VF_PERMANENT,
len, NULL);
newtime->v_plot = new;
for (i = 0; i < len; i++)
newtime->v_realdata[i] = oldtime->v_realdata[istart + i];
new->pl_scale = new->pl_dvecs = newtime;
/* copy the vectors from tstart to tstop */
if (wl) {
while (wl) {
v = vec_fromplot(wl->wl_word, old);
if (!v) {
fprintf(cp_err, "Error: no such vector %s\n",
wl->wl_word);
wl = wl->wl_next;
continue;
}
nv = copycut(v, newtime, istart, istop);
vec_new(nv);
wl = wl->wl_next;
}
}
else {
for (v = old->pl_dvecs; v; v = v->v_next) {
if (v == old->pl_scale)
continue;
/* Don't copy vectors that are too short */
if (v->v_length < istop)
continue;
nv = copycut(v, newtime, istart, istop);
vec_new(nv);
}
}
}

View File

@ -7,6 +7,7 @@
#define ngspice_LINEAR_H #define ngspice_LINEAR_H
void com_linearize(wordlist *wl); void com_linearize(wordlist *wl);
void com_cutout(wordlist *wl);
#endif #endif

View File

@ -1347,3 +1347,66 @@ static bool plot_prefix(const char *pre, const char *str)
else else
return (TRUE); return (TRUE);
} }
struct dvec*
copycut(struct dvec* v, struct dvec* newscalevec, int istart, int istop)
{
struct dvec* nv;
int i;
int len = istop - istart;
if (!v) {
return (struct dvec*)NULL;
}
/* Make a copy with the VF_PERMANENT bit cleared in v_flags */
nv = dvec_alloc(copy(v->v_name),
v->v_type,
v->v_flags,// & ~VF_PERMANENT,
len, NULL);
/* Copy the data to the new vector */
if (isreal(v)) {
for (i = 0; i < len; i++) {
nv->v_realdata[i] = v->v_realdata[istart + i];
}
}
else {
for (i = 0; i < len; i++) {
nv->v_compdata[i] = v->v_compdata[istart + i];
}
}
nv->v_minsignal = v->v_minsignal;
nv->v_maxsignal = v->v_maxsignal;
nv->v_gridtype = v->v_gridtype;
nv->v_plottype = v->v_plottype;
/* Modified to copy the rlength of origin to destination vecor
* instead of always putting it to 0.
* As when it comes to make a print does not leave M1 @ @ M1 = 0.0,
* to do so in the event that rlength = 0 not print anything on screen
* nv-> v_rlength = 0;
* Default -> v_rlength = 0 and only if you come from a print or M1 @
* @ M1 [all] rlength = 1, after control is one of
* if (v-> v_rlength == 0) com_print (wordlist * wl)
*/
nv->v_rlength = v->v_rlength;
nv->v_outindex = 0; /*XXX???*/
nv->v_linestyle = 0; /*XXX???*/
nv->v_color = 0; /*XXX???*/
nv->v_defcolor = v->v_defcolor;
nv->v_numdims = v->v_numdims;
/* Copy defined dimensions */
(void)memcpy(nv->v_dims, v->v_dims,
(size_t)v->v_numdims * sizeof * v->v_dims);
nv->v_plot = newscalevec->v_plot;
nv->v_next = NULL;
nv->v_link2 = NULL;
nv->v_scale = newscalevec;
return nv;
} /* end of function copycut */

View File

@ -366,6 +366,7 @@ extern struct plot *get_plot(const char *name);
extern void plot_new(struct plot *pl); extern void plot_new(struct plot *pl);
extern char *vec_basename(struct dvec *v); extern char *vec_basename(struct dvec *v);
extern void vec_transpose(struct dvec *v); extern void vec_transpose(struct dvec *v);
extern struct dvec* copycut(struct dvec* ov, struct dvec* newscalevec, int istart, int istop);
/* main.c */ /* main.c */
extern bool ft_intrpt; extern bool ft_intrpt;