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:
parent
71338c3271
commit
fe28feae4e
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue