Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>It turns out the result of my gut feeling and Diego's method is an average of the integral. I still don't like that name, so I have described the algorithm and have <a href="https://math.stackexchange.com/questions/530767">asked on Math.SE what to call this, which got migrated to "Cross Validated", Stats.SE </a>.</p> <p>I Updated graphs after a massive edit of my Math.SE question. It turns out I'm taking the average of a closed integral of the derivative of the data. :P First, we gather the data:</p> <p><img src="https://i.stack.imgur.com/W5oXL.png" alt="Plot of data gathered, highlighting the dip"></p> <p>Next is the "derivative": step through the original data array to form the <kbd>deltas</kbd> array which is the rise of ADC values from one 0.75° step to the next. "Rise" or "slope" is what the derivative is: dy/dx. </p> <p>With the "slope" or average leveled out, I can find multiple negative <kbd>deltas</kbd> in a row, sum them, then divide by the count at the end of the dip. The sum is an integral of the area between average and the <kbd>deltas</kbd> and when the dip goes back positive, I can divide the sum by the count of the dips.</p> <p><img src="https://i.stack.imgur.com/FjzSS.png" alt="Average of the Numerical Integral of the derivative"></p> <p>During testing, I came up with a cutoff value for this average of the integral at 2.6. That was a great measure of my "gut instinct" looking at the plot thinking a part was good or bad.</p> <p>In case someone else finds themselves trying to quantify this, here's the code I implemented. Note that it is only looking for negative dips. Also, dipCountLimit is defined elsewhere as 5. In addition to the dip detector/accumulator (ie Numerical Integrator) I also have a spike detector that arbitrarily flags the test as bad if any data points stray from the average by the amount of average + standard deviation. AVG+STD DEV as a spike limit was chosen arbitrarily based on the observed plots of the parts it would fail.</p> <pre><code>int dipdx=0; // inDipFlag also counts the length of this dip int inDipFlag=0; float dips[140] = { 0.0 }; for( int idx=0; idx&lt;stop; idx++ ){ const float diffFromAvg = deltas[idx] - line-&gt;AdcAvgRise; // state machine to monitor dips const int _stop = stop-1; if( diffFromAvg &lt; 0 &amp;&amp; idx &lt; _stop ) { // check NEXT data point for negative diff &amp; set dipFlag to put state in dip const float nextDiff = deltas[idx+1] - line-&gt;AdcAvgRise; if( nextDiff &lt; 0 &amp;&amp; inDipFlag == 0 ) inDipFlag = 1; // already IN a dip, and next diff is negative if( nextDiff &lt; 0 &amp;&amp; inDipFlag &gt; 0 ) { inDipFlag++; } // accumulate this dip dips[dipdx]+= diffFromAvg; // next data point ends this dip and we advance dipdx to next dip if( inDipFlag &gt; 0 &amp;&amp; nextDiff &gt; 0 ) { if( inDipFlag &lt; dipCountLimit ){ // reset the accumulator, do not advance dipdx to next entry dips[dipdx]=0.0; } else { // change this entry's value from dip sum to its ratio dips[dipdx] = -dips[dipdx]/inDipFlag; // advance dipdx to next entry dipdx++; } // Next diff isn't negative, so the dip is done inDipFlag = 0; } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload