Experimental Physics and
| |||||||||||||||
|
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;
*>>>>>>>>>>>>>> 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); } -- +-------------------------------------------------+ | Rolf Keitel, TRIUMF Tel: (604) 222-7453 | | Group Leader ISAC Controls Fax: (604) 222-7307 | | and Electronics Development | | Vancouver, B.C., Canada | +-------------------------------------------------+
| ||||||||||||||
ANJ, 02 Sep 2010 |
·
Home
·
News
·
About
·
Base
·
Modules
·
Extensions
·
Distributions
·
Download
·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing · |