- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
how to calculate yield for many columns with embedded spec limits
Hi,
I have over 60 columns where individual spec limits are embeded in column properties. I like to calculate the yield for each row as Pass/Fail. I appreciate any script that will do this. I checked the JMP discussion and found one script that does yield but each columns is assumed to be pass or fail (1 or 0). Thanks
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: how to calculate yield for many columns with embedded spec limits
My error, an ")" was left out of the last statement. It should be:
Eval( Parse( "dt << New Column( \!"Row Pass/Fail\!", formula( If( Min(" || foundCols || " ) == 1, 1, 0 ) ))" ) );
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: how to calculate yield for many columns with embedded spec limits
Here is a script that will create new columns that numerically contain 0/1 and display as Fail/Pass
Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA\Semiconductor Capability.jmp" );
// Get all numeric columns
colList = dt << get column names( numeric, string );
foundCols = "";
// Loop across the columns and generate the test pass/fails
For( i = 1, i <= N Items( colList ), i++,
spec = Column( dt, colList[i] ) << get property( "Spec Limits" );
dt << clear select;
If( Is Empty( spec ) == 0,
dt << New Column( (Column( dt, colList[i] ) << get name) || " Pass/Fail" );
If( Is Missing( Try( spec["LSL"], . ) ) == 0,
dt << select where( As Column( dt, colList[i] ) < spec["LSL"] );
Try( Column( dt, N Cols( dt ) )[dt << get selected rows] = 0 );
);
If( Is Missing( Try( spec["USL"], . ) ) == 0,
dt << select where( As Column( dt, colList[i] ) > spec["USL"], current selection( "extend" ) );
Try( Column( dt, N Cols( dt ) )[dt << get selected rows] = 0 );
);
dt << invert row selection;
Try( Column( dt, N Cols( dt ) )[dt << get selected rows] = 1 );
Column( dt, N Cols( dt ) ) << set property( "Value Labels", {0 = "Fail", 1 = "Pass"} );
If( foundCols == "",
foundCols = ":Name(\!"" || (Column( dt, colList[i] ) << get name) || " Pass/Fail\!")",
foundCols = foundCols || ", " || ":Name(\!"" || (Column( dt, colList[i] ) << get name) || " Pass/Fail\!")"
);
);
);
// Create the Row Pass/Fail
Eval( Parse( "dt << New Column( \!"Row Pass/Fail\!", formula( If( Min(" || foundCols || " ) == 1, 1, 0 ) )" ) );
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: how to calculate yield for many columns with embedded spec limits
Thanks Jim. This is exactly what I wanted.
I ran the script and found this error. A column is created with title "Row Pass/Fail" and it is all zero.
Unexpected end of input. Perhaps there is a missing "," or ")".
Trying to parse arguments of function "New Column".
Line 1 Column 3272: ...s/Fail") ) == 1, 1, 0 ) )►...
Resolution Problem with Formula for Column Wafer ID in lot ID:
Column( "Row Pass/Fail" )
Thanks for your continuous support.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: how to calculate yield for many columns with embedded spec limits
My error, an ")" was left out of the last statement. It should be:
Eval( Parse( "dt << New Column( \!"Row Pass/Fail\!", formula( If( Min(" || foundCols || " ) == 1, 1, 0 ) ))" ) );
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: how to calculate yield for many columns with embedded spec limits
Thanks Jim. It works now.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: how to calculate yield for many columns with embedded spec limits
Why this functionality isn't built in to JMP I don't understand, but how could this script be changed so the pass/fail columns will be dynamic? I would like to be able to adjust the specs to determine effect on yield. The way it is now I would have to delete the added columns each time I wanted to reevaluate the yield.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: how to calculate yield for many columns with embedded spec limits
The definition of Spec Limits, typically does not contain their dynamic calculation. They are set based on design limits, etc. That aside, regarding your question, do you invision setting the limits dynamically for all columns(parameters) at the same time? That is, will the limits be set the same for each parameter? Or would you set each individually? Using a Data Filter in conjuction with column formulas could handle your request.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: how to calculate yield for many columns with embedded spec limits
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: how to calculate yield for many columns with embedded spec limits
Additional detail, I have 75-150 parameters and very few of them have the same limits. In a recent experience, I have three parameters driving yield, and a limited amount of spec relief that I can expect to receive. I need to know which combination of spec changes will yield the biggest improvement, while minimizing the magnitude of the changes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: how to calculate yield for many columns with embedded spec limits
Below is a script that is a very basic, but a good starting point for the development of an interactive yield calculator. Your requirement is a very neat idea. Maybe you can develop and add to the File Exchange a new addin, or maybe someone else will do such. But, here is my starting point script:
Names Default To Here( 1 );
// Create a sample data table
dt = New Table( "Yield",
Add Rows( 40 ),
New Column( "Parm 1",
Numeric,
"Continuous",
Format( "Fixed Dec", 5, 0 ),
Set Property( "Spec Limits", {LSL( 57 ), USL( 67 ), Show Limits( 0 )} ),
Set Values(
[59, 61, 55, 66, 52, 60, 61, 51, 60, 61, 56, 65, 63, 58, 59, 61, 62, 65, 63, 62, 63, 64, 65, 64, 68, 64, 69, 62, 64, 67, 65, 66,
62, 66, 65, 60, 68, 62, 68, 70]
)
),
New Column( "Parm 2",
Numeric,
"Continuous",
Format( "Fixed Dec", 5, 0 ),
Set Property( "Spec Limits", {LSL( 80 ), USL( 140 ), Show Limits( 0 )} ),
Set Values(
[95, 123, 74, 145, 64, 84, 128, 79, 112, 107, 67, 98, 105, 95, 79, 81, 91, 142, 84, 85, 93, 99, 119, 92, 112, 99, 113, 92, 112,
128, 111, 105, 104, 106, 112, 115, 128, 116, 134, 172]
)
),
New Column( "Parm 1 Pass/Fail",
Numeric,
"Continuous",
Format( "Best", 12 ),
Value Labels( {0 = "Fail", 1 = "Pass"} ),
Use Value Labels( 1 ),
Set Values(
[1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0]
)
),
New Column( "Parm 2 Pass/Fail",
Numeric,
"Continuous",
Format( "Best", 12 ),
Value Labels( {0 = "Fail", 1 = "Pass"} ),
Use Value Labels( 1 ),
Set Values(
[1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]
)
)
);
// A function to set the Pass/Fail columns based upon the current Spec Limits
setPassFail = Function( {Parm},
USL = (Column( dt, parm ) << get property( "Spec Limits" ))["USL"];
LSL = (Column( dt, parm ) << get property( "Spec Limits" ))["LSL"];
Column( dt, parm || " Pass/Fail" )[dt << get rows where( As Column( dt, parm ) >= LSL & As Column( dt, parm ) <= USL )] = 1;
Column( dt, parm || " Pass/Fail" )[dt << get rows where( As Column( dt, parm ) < LSL | As Column( dt, parm ) > USL )] = 0;
);
//Calculate the yield for all Pass/Fail columns
calculateYield = Function( {},
overallYield = 0;
numberOfRowsThatPassed = 0;
numberOfRowsThatFailed = 0;
For( i = 1, i <= N Rows( dt ), i++,
If( Sum( :Name( "Parm 1 Pass/Fail" )[i], :Name( "Parm 2 Pass/Fail" )[i] ) == N Items( colNamesList ),
numberOfRowsThatPassed++,
numberOfRowsThatFailed
++)
);
overallYield = numberOfRowsThatPassed / (numberOfRowsThatPassed + numberOfRowsThatFailed);
);
// Display the Yield Changing Window
nw = New Window( "Interactive Yield Calculation",
Lineup Box( N Col( 2 ),
V List Box(
Text Box( "Parm 1" ),
p1Upper = Col Maximum( :Name( "Parm 1" ) );
p1Lower = Col Minimum( :Name( "Parm 1" ) );
p1 = Range Slider Box(
Col Mean( :Name( "Parm 1" ) ) - 6 * Col Std Dev( :Name( "Parm 1" ) ),
Col Mean( :Name( "Parm 1" ) ) + 6 * Col Std Dev( :Name( "Parm 1" ) ),
p1Lower,
p1Upper,
Eval(
Substitute(
Expr(
:Name( "Parm 1" ) << set property( "Spec Limits", {LSL( _LSL_ ), USL( _USL_ ), Show Limits( 0 )} )
),
Expr( _LSL_ ), p1Lower,
Expr( _USL_ ), p1Upper
)
);
returned = setPassFail( "Parm 1" );
cYield = calculateYield();
yieldVal << set( cYield );
);,
Text Box( "Parm 2" ),
p2Upper = Col Maximum( :Name( "Parm 2" ) );
p2Lower = Col Minimum( :Name( "Parm 2" ) );
p2 = Range Slider Box(
Col Mean( :Name( "Parm 2" ) ) - 6 * Col Std Dev( :Name( "Parm 2" ) ),
Col Mean( :Name( "Parm 2" ) ) + 6 * Col Std Dev( :Name( "Parm 2" ) ),
p2Lower,
p2Upper,
Eval(
Substitute(
Expr(
:Name( "Parm 2" ) << set property( "Spec Limits", {LSL( _LSL_ ), USL( _USL_ ), Show Limits( 0 )} )
),
Expr( _LSL_ ), p2Lower,
Expr( _USL_ ), p2Upper
)
);
returned = setPassFail( "Parm 2" );
cYield = calculateYield();
yieldVal << set( cYield );
);,
),
V List Box( Text Box( "Yield" ), yieldVal = Number Edit Box() )
),
cYield = calculateYield();
yieldVal << set( cYield );
);