Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017 
<== Date ==> <== Thread ==>

Subject: Re: bug in break-point table conversion
From: "D. Peter Siddons" <siddons@bnl.gov>
To: Rolf Keitel <rolf@triumf.ca>
Cc: tech_talk <tech-talk@aps.anl.gov>
Date: Mon, 15 May 2006 17:56:39 -0400
I had also just run into this. It is also a bug in the makeBpt program to generate a table from raw data. It produces nonsense if the raw ADC values are in decreasing order and the engineering values are increasing. I didn't try it with positive slope but reversed data order. I thought that simply reversing the table order fixed it, but apparently not.
Pete.



Rolf Keitel wrote:
There is a problem with break-point table conversion from engineering to raw values ( function cvtEngToRawBpt in file cvtBpt.c).
The function returns incorrect results, if the breakpoint table has negative slopes, i.e. if engineering values decrease with increasing raw values.
The faulty routine and one possible fix are attached below.
Here is the printout from a test program, which converts raw values to engineering values and back to raw values:


Breakpoint Table:
0 -- 186 475 slope -0.203488
1 -- 358 440 slope -0.196078
2 -- 562 400 slope -0.199601
3 -- 1063 300 slope -0.207612
4 -- 1641 180 slope -0.22409
5 -- 1998 100 slope -0.257732
6 -- 2192 50 slope -0.266667
7 -- 2267 30 slope -0.101695
8 -- 2326 24 slope -0.0261438
9 -- 2632 16 slope -0.0217391
10 -- 2908 10 slope -0.0139373
11 -- 3195 6 slope -0.0152672

    raw     eng         raw
bit:  500 ==> 412.157 ==> 494.829 (index 1 0)
bit:  800 ==> 352.495 ==> 788.025 (index 2 0)
bit: 1100 ==> 292.318 ==> 1083.75 (index 3 0)
bit: 1400 ==> 230.035 ==> 1389.83 (index 3 0)
bit: 1700 ==> 166.779 ==> 1700.69 (index 4 0)
bit: 2000 ==> 99.4845 ==> 2031.39 (index 5 0)
bit: 2300 ==> 26.6441 ==> 2389.35 (index 7 0)
bit: 2600 ==> 16.8366 ==> 2437.55 (index 8 0)
bit: 2900 ==> 10.1739 ==> 2470.29 (index 9 0)


>>>>>>>>>>>>>> faulty function


long cvtEngToRawBpt(double *pval,short linr,short init,
     void **ppbrk,short *plbrk)
{     double    val=*pval;
    long    status=0;
    brkTable    *pbrkTable;
    brkInt    *pInt;         brkInt    *pnxtInt;
    short    lbrk;
    int    number;


if(linr < 2) return(-1); if(init==TRUE || *ppbrk == NULL) { /*must find breakpoint table*/ pbrkTable = findBrkTable(linr); if(!pbrkTable) return(S_dbLib_badField); *ppbrk = (void *)pbrkTable; /* Just start at the beginning */ *plbrk=0; } pbrkTable = (struct brkTable *)*ppbrk; number = pbrkTable->number; lbrk = *plbrk; /*make sure we dont go off end of table*/ if( (lbrk+1) >= number ) lbrk--; pInt = pbrkTable->papBrkInt[lbrk]; pnxtInt = pbrkTable->papBrkInt[lbrk+1]; /* find entry for increased value */ while( (pnxtInt->eng) <= val ) { lbrk++; pInt = pbrkTable->papBrkInt[lbrk]; if( lbrk >= number-1) { status=1; break; } pnxtInt = pbrkTable->papBrkInt[lbrk+1]; } while( (pInt->eng) > val) { if(lbrk==0) { status=1; break; } lbrk--; pInt = pbrkTable->papBrkInt[lbrk]; } if(pInt->slope!=0){ *plbrk = lbrk; *pval = pInt->raw + (val - pInt->eng) / pInt->slope; } else { return(status); } return(0); }

*>>>>>>>>>>>>>> possible fix*

long cvtEngToRawBpt(double *pval,short linr,short init,
     void **ppbrk,short *plbrk)
{     double    val=*pval;
    long    status=0;
    brkTable    *pbrkTable;
    brkInt    *pInt;         brkInt    *pnxtInt;
    short    lbrk;
    int    number;


if(linr < 2) return(-1); if(init==TRUE || *ppbrk == NULL) { /*must find breakpoint table*/ pbrkTable = findBrkTable(linr); if(!pbrkTable) return(S_dbLib_badField); *ppbrk = (void *)pbrkTable; /* Just start at the beginning */ *plbrk=0; } pbrkTable = (struct brkTable *)*ppbrk; number = pbrkTable->number; lbrk = *plbrk; /*make sure we dont go off end of table*/ if( (lbrk+1) >= number ) lbrk--; pInt = pbrkTable->papBrkInt[lbrk]; pnxtInt = pbrkTable->papBrkInt[lbrk+1]; if (pInt->slope > 0) { /* positive slopes */ /* find entry for increased value */ while( (pnxtInt->eng) <= val ) { lbrk++; pInt = pbrkTable->papBrkInt[lbrk]; if( lbrk >= number-1) { status=1; break; } pnxtInt = pbrkTable->papBrkInt[lbrk+1]; } while( (pInt->eng) > val) { if(lbrk==0) { status=1; break; } lbrk--; pInt = pbrkTable->papBrkInt[lbrk]; } } else { /* negative slopes */ /* find entry for decreased value */ while( (pnxtInt->eng) >= val ) { lbrk++; pInt = pbrkTable->papBrkInt[lbrk]; if( lbrk >= number-1) { status=1; break; } pnxtInt = pbrkTable->papBrkInt[lbrk]; } while( (pInt->eng) < val) { if(lbrk==0) { status=1; break; } lbrk--; pInt = pbrkTable->papBrkInt[lbrk]; } } if(pInt->slope!=0){ *plbrk = lbrk; *pval = pInt->raw + (val - pInt->eng) / pInt->slope; } else { return(status); } return(0); }

Replies:
Re: bug in break-point table conversion Andrew Johnson
References:
bug in break-point table conversion Rolf Keitel

Navigate by Date:
Prev: Fw: epics base compile fails Bob Soliday
Next: Re: bug in break-point table conversion Andrew Johnson
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017 
Navigate by Thread:
Prev: bug in break-point table conversion Rolf Keitel
Next: Re: bug in break-point table conversion Andrew Johnson
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017 
ANJ, 02 Sep 2010 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·