update FIND ... WHEN measurements

This commit is contained in:
h_vogt 2011-02-19 22:11:45 +00:00
parent 7880d5bd8e
commit ebda0af288
4 changed files with 170 additions and 68 deletions

View File

@ -1,3 +1,7 @@
2011-02-19 Holger Vogt
* ngspice.h: _snprintf for MS Visual Studio
* measure.c, com_measure.c: update FIND .. WHEN measurements
2011-02-19 Robert Larice 2011-02-19 Robert Larice
* configure.ac , * configure.ac ,
* examples/transient-noise/shot_ng.cir , * examples/transient-noise/shot_ng.cir ,

View File

@ -373,15 +373,20 @@ static void com_measure_when(
int measurement_pending; int measurement_pending;
int init_measured_value; int init_measured_value;
bool ac_check = FALSE, sp_check = FALSE, dc_check = FALSE, tran_check = FALSE ; bool ac_check = FALSE, sp_check = FALSE, dc_check = FALSE, tran_check = FALSE ;
double value, prevValue; bool has_d2 = FALSE;
double value, prevValue, value2, prevValue2;
double scaleValue, prevScaleValue; double scaleValue, prevScaleValue;
enum ValSide { S_ABOVE_VAL, S_BELOW_VAL }; enum ValSide { S_ABOVE_VAL, S_BELOW_VAL };
enum ValEdge { E_RISING, E_FALLING }; enum ValEdge { E_RISING, E_FALLING };
struct dvec *d, *dScale; struct dvec *d, *d2, *dScale;
d = vec_get(meas->m_vec); d = vec_get(meas->m_vec);
if (meas->m_vec2) {
d2 = vec_get(meas->m_vec2);
has_d2 = TRUE;
}
dScale = plot_cur->pl_scale; dScale = plot_cur->pl_scale;
if (d == NULL) { if (d == NULL) {
@ -389,13 +394,18 @@ static void com_measure_when(
return; return;
} }
if ((has_d2) && (d == NULL)) {
fprintf(cp_err, "Error: no such vector as %s.\n", meas->m_vec2);
return;
}
if (dScale == NULL) { if (dScale == NULL) {
fprintf(cp_err, "Error: no scale vector.\n"); fprintf(cp_err, "Error: no scale vector.\n");
return; return;
} }
prevValue =0; prevValue =0.;
prevScaleValue =0; prevValue2 =0.;
prevScaleValue =0.;
first =0; first =0;
measurement_pending=0; measurement_pending=0;
init_measured_value=1; init_measured_value=1;
@ -415,9 +425,6 @@ static void com_measure_when(
for (i=0; i < d->v_length; i++) { for (i=0; i < d->v_length; i++) {
// value = d->v_realdata[i];
// scaleValue = dTime->v_realdata[i];
if (ac_check) { if (ac_check) {
if (d->v_compdata) if (d->v_compdata)
value = get_value(meas, d, i); //d->v_compdata[i].cx_real; value = get_value(meas, d, i); //d->v_compdata[i].cx_real;
@ -436,6 +443,24 @@ static void com_measure_when(
value = d->v_realdata[i]; value = d->v_realdata[i];
scaleValue = dScale->v_realdata[i]; scaleValue = dScale->v_realdata[i];
} }
if (has_d2) {
if (ac_check) {
if (d2->v_compdata)
value2 = get_value(meas, d2, i); //d->v_compdata[i].cx_real;
else
value2 = d2->v_realdata[i];
}
else if (sp_check) {
if (d2->v_compdata)
value2 = get_value(meas, d2, i); //d->v_compdata[i].cx_real;
else
value2 = d2->v_realdata[i];
}
else {
value2 = d2->v_realdata[i];
}
}
/* 'dc' is special: it may start at an arbitrary scale value. /* 'dc' is special: it may start at an arbitrary scale value.
Use m_td to store this value, a delay TD does not make sense */ Use m_td to store this value, a delay TD does not make sense */
if ((dc_check) && (i==0)) if ((dc_check) && (i==0))
@ -451,70 +476,136 @@ static void com_measure_when(
if ((first > 1) && (dc_check && (meas->m_td == scaleValue))) if ((first > 1) && (dc_check && (meas->m_td == scaleValue)))
first = 1; first = 1;
if (first == 1) { if (first == 1)
// initialise if (has_d2) {
crossCnt =0; // initialise
if (value < meas->m_val) { crossCnt =0;
section = S_BELOW_VAL; if (value < value2) {
if ( (prevValue <= meas->m_val) && (value >= meas->m_val) ) { section = S_BELOW_VAL;
fallCnt =1; if ( (prevValue <= value2) && (value >= value2) ) {
crossCnt =1; fallCnt =1;
} crossCnt =1;
}
} else { } else {
section = S_ABOVE_VAL; section = S_ABOVE_VAL;
if ( (prevValue <= meas->m_val) && (value >= meas->m_val) ) { if ( (prevValue <= value2) && (value >= value2) ) {
riseCnt =1; riseCnt =1;
crossCnt =1; crossCnt =1;
} }
} }
fflush( stdout ) ; fflush( stdout ) ;
} }
else {
// initialise
crossCnt =0;
if (value < meas->m_val) {
section = S_BELOW_VAL;
if ( (prevValue <= meas->m_val) && (value >= meas->m_val) ) {
fallCnt =1;
crossCnt =1;
}
} else {
section = S_ABOVE_VAL;
if ( (prevValue <= meas->m_val) && (value >= meas->m_val) ) {
riseCnt =1;
crossCnt =1;
}
}
fflush( stdout ) ;
}
if (first > 1) { if (first > 1) {
if ( (section == S_BELOW_VAL) && (value >= meas->m_val) ) { if (has_d2) {
section = S_ABOVE_VAL; if ( (section == S_BELOW_VAL) && (value >= value2) ) {
crossCnt++; section = S_ABOVE_VAL;
riseCnt++; crossCnt++;
if( meas->m_fall != MEASURE_LAST_TRANSITION ){ riseCnt++;
/* we can measure rise/cross transition if the user if( meas->m_fall != MEASURE_LAST_TRANSITION ){
* has not requested a last fall transition */ /* we can measure rise/cross transition if the user
measurement_pending=1; * has not requested a last fall transition */
} measurement_pending=1;
}
} else if ( (section == S_ABOVE_VAL) && (value <= meas->m_val) ) { } else if ( (section == S_ABOVE_VAL) && (value <= value2) ) {
section = S_BELOW_VAL; section = S_BELOW_VAL;
crossCnt++; crossCnt++;
fallCnt++; fallCnt++;
if( meas->m_rise != MEASURE_LAST_TRANSITION ){ if( meas->m_rise != MEASURE_LAST_TRANSITION ){
/* we can measure fall/cross transition if the user /* we can measure fall/cross transition if the user
* has not requested a last rise transition */ * has not requested a last rise transition */
measurement_pending=1; measurement_pending=1;
} }
} }
if ((crossCnt == meas->m_cross) || (riseCnt == meas->m_rise) || (fallCnt == meas->m_fall)) { if ((crossCnt == meas->m_cross) || (riseCnt == meas->m_rise) || (fallCnt == meas->m_fall)) {
/* user requested an exact match of cross, rise, or fall /* user requested an exact match of cross, rise, or fall
* exit when we meet condition */ * exit when we meet condition */
meas->m_measured = prevScaleValue + (meas->m_val - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue); // meas->m_measured = prevScaleValue + (value2 - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue);
return; meas->m_measured = prevScaleValue + (prevValue2 - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue - value2 + prevValue2);
return;
}
if ( measurement_pending ){
if( (meas->m_cross == MEASURE_DEFAULT) && (meas->m_rise == MEASURE_DEFAULT) && (meas->m_fall == MEASURE_DEFAULT) ){
/* user didn't request any option, return the first possible case */
meas->m_measured = prevScaleValue + (prevValue2 - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue - value2 + prevValue2);
return;
} else if( (meas->m_cross == MEASURE_LAST_TRANSITION) || (meas->m_rise == MEASURE_LAST_TRANSITION) || (meas->m_fall == MEASURE_LAST_TRANSITION) ){
meas->m_measured = prevScaleValue + (prevValue2 - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue - value2 + prevValue2);
/* no return - look for last */
init_measured_value=0;
}
measurement_pending=0;
}
} }
if ( measurement_pending ){ else {
if( (meas->m_cross == MEASURE_DEFAULT) && (meas->m_rise == MEASURE_DEFAULT) && (meas->m_fall == MEASURE_DEFAULT) ){ if ( (section == S_BELOW_VAL) && (value >= meas->m_val) ) {
/* user didn't request any option, return the first possible case */ section = S_ABOVE_VAL;
meas->m_measured = prevScaleValue + (meas->m_val - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue); crossCnt++;
return; riseCnt++;
} else if( (meas->m_cross == MEASURE_LAST_TRANSITION) || (meas->m_rise == MEASURE_LAST_TRANSITION) || (meas->m_fall == MEASURE_LAST_TRANSITION) ){ if( meas->m_fall != MEASURE_LAST_TRANSITION ){
meas->m_measured = prevScaleValue + (meas->m_val - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue); /* we can measure rise/cross transition if the user
/* no return - look for last */ * has not requested a last fall transition */
init_measured_value=0; measurement_pending=1;
} }
measurement_pending=0;
} else if ( (section == S_ABOVE_VAL) && (value <= meas->m_val) ) {
section = S_BELOW_VAL;
crossCnt++;
fallCnt++;
if( meas->m_rise != MEASURE_LAST_TRANSITION ){
/* we can measure fall/cross transition if the user
* has not requested a last rise transition */
measurement_pending=1;
}
}
if ((crossCnt == meas->m_cross) || (riseCnt == meas->m_rise) || (fallCnt == meas->m_fall)) {
/* user requested an exact match of cross, rise, or fall
* exit when we meet condition */
meas->m_measured = prevScaleValue + (meas->m_val - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue);
return;
}
if ( measurement_pending ){
if( (meas->m_cross == MEASURE_DEFAULT) && (meas->m_rise == MEASURE_DEFAULT) && (meas->m_fall == MEASURE_DEFAULT) ){
/* user didn't request any option, return the first possible case */
meas->m_measured = prevScaleValue + (meas->m_val - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue);
return;
} else if( (meas->m_cross == MEASURE_LAST_TRANSITION) || (meas->m_rise == MEASURE_LAST_TRANSITION) || (meas->m_fall == MEASURE_LAST_TRANSITION) ){
meas->m_measured = prevScaleValue + (meas->m_val - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue);
/* no return - look for last */
init_measured_value=0;
}
measurement_pending=0;
}
} }
} }
first ++; first ++;
prevValue = value; prevValue = value;
if (has_d2)
prevValue2 = value2;
prevScaleValue = scaleValue; prevScaleValue = scaleValue;
} }
@ -1346,7 +1437,7 @@ get_measure2(
if (!ciprefix("tran", plot_cur->pl_typename) && !ciprefix("ac", plot_cur->pl_typename) && if (!ciprefix("tran", plot_cur->pl_typename) && !ciprefix("ac", plot_cur->pl_typename) &&
!ciprefix("dc", plot_cur->pl_typename) && !ciprefix("sp", plot_cur->pl_typename)) { !ciprefix("dc", plot_cur->pl_typename) && !ciprefix("sp", plot_cur->pl_typename)) {
fprintf(cp_err, "Error: measure limited to tran, dc or ac analysis\n"); fprintf(cp_err, "Error: measure limited to tran, dc, sp, or ac analysis\n");
return MEASUREMENT_FAILURE; return MEASUREMENT_FAILURE;
} }
@ -1529,7 +1620,7 @@ get_measure2(
} }
measure_at(meas, measFind->m_measured); measure_at(meas, measFind->m_measured);
meas->m_measured = measFind->m_measured; meas->m_at = measFind->m_measured;
} else { } else {
measure_at(meas, meas->m_at); measure_at(meas, meas->m_at);

View File

@ -44,21 +44,27 @@ extern bool rflag;
void void
com_meas(wordlist *wl) { com_meas(wordlist *wl) {
/* wl: in, input line of meas command */ /* wl: in, input line of meas command */
char *line_in, *outvar, newvec[1000], *vec_found, *token, *equal_ptr, newval[256]; char *line_in, *outvar, newvec[1000];
wordlist * wl_count, *wl_let, *wl_index; wordlist * wl_count, *wl_let;
int fail, err=0; #ifdef not
double result = 0; char *vec_found, *token, *equal_ptr, newval[256];
wordlist *wl_index;
struct dvec *d; struct dvec *d;
int err=0;
#endif
int fail;
double result = 0;
if (!wl) { if (!wl) {
com_display(NULL); com_display(NULL);
return; return;
} }
wl_count = wl; wl_count = wl;
#ifdef not
/* check each wl entry, if it contain '=' and if the following token is /* check each wl entry, if it contain '=' and if the following token is
a vector. If yes, replace this vector by its value */ a vector. If yes, replace this vector by its value */
wl_index = wl; wl_index = wl;
while ( wl_index) { while ( wl_index) {
token = wl_index->wl_word; token = wl_index->wl_word;
/* find the vector vec_found, next token after each '=' sign. /* find the vector vec_found, next token after each '=' sign.
@ -103,7 +109,7 @@ com_meas(wordlist *wl) {
} }
wl_index = wl_index->wl_next; wl_index = wl_index->wl_next;
} }
#endif
line_in = wl_flatten(wl); line_in = wl_flatten(wl);
/* get output var name */ /* get output var name */

View File

@ -171,6 +171,7 @@
#define open _open #define open _open
#define write _write #define write _write
#define strcasecmp _stricmp #define strcasecmp _stricmp
#define snprintf _snprintf
#define inline __inline #define inline __inline
#endif #endif