/*dt = Open( "$SAMPLE_STIPS/Wafer Stacked Small.jmp" );
dt << Graph Builder(
Size( 534, 464 ),
Show Control Panel( 0 ),
Graph Spacing( 4 ),
Variables( X( :X_Die ), Y( :Y_Die ), Wrap( :Lot, Levels per Row( 3 ) ), Color( :Defects, Summary Statistic( "Sum" ) ) ),
Elements( Heatmap( X, Y, Legend( 5 ) ) ),
SendToReport(
Dispatch( {}, "X_Die", ScaleBox, {Min( -22 ), Max( 22 ), Inc( 5 ), Minor Ticks( 4 )} ),
Dispatch( {}, "Y_Die", ScaleBox, {Min( -20 ), Max( 22 ), Inc( 5 ), Minor Ticks( 4 )} ),
)
);*/
// second part --------------------------------------------------------
//Names Default To Here( 1 );
New Namespace(
"LineScan"
);
LineScan:LS_Initialize = Function( {}, // variables used for communication between the Linescan and the Mousetrap
LineScan:MyfirstClick = 1;
LineScan:startx = 0;
LineScan:starty = 0;
LineScan:exx = 0;
LineScan:exy = 0;
LineScan:mouse_released = 0;
LineScan:gb = 1;
LineScan:dt = 1;
);
LineScan:CloseTemporaryTables() = Function( {},
dtList = Get Data Table List();
For Each( {checkDt, idx}, dtList,
If( Not(IsMissing(Regex( checkDt << get name(), "tempDTLineCutXY.*" ))) ,
Print( checkDt << get name() || ": close" );
Close( checkDt, no save )
)
);
);
LineScan:LS_findVariables = Function( {},
foundX = 0;
foundY = 0;
foundCol = 0;
allVariables = (LineScan:gb << get variables);
For Each( {var, idx}, allVariables,
If( Arg( var[2] ) == "X",
xVar = var[1];
foundX = 1;
);
If( Arg( var[2] ) == "Y",
yVar = var[1];
foundY = 1;
);
If( Arg( var[2] ) == "Color",
colVar = var[1];
foundCol = 1;
);
);
LineScan:myStatistics = "Mean";
LineScan:myGroups = {};
gbScript = LineScan:gb << Get Script;
numArgs = N Arg( gbScript );
For( i = 1, i <= numArgs, i++,
If( Head Name( Arg( gbScript, i ) ) == "Variables",
//Print( "found variables", i );
nVariables = N Arg( Arg( gbScript, i ) );
For( k = 1, k <= nVariables, k++,
If(
Head Name( Arg( Arg( gbScript, i ), k ) ) == "Color",
//Print( "found color", k );
nEntries = N Arg( Arg( gbScript, i ) );
For( m = 1, m <= nEntries, m++,
If( Head Name( Arg( Arg( Arg( gbScript, i ), k ), m ) ) == "Summary Statistic",
//Print( "found stat", m );
LineScan:myStatistics = Arg( Arg( Arg( Arg( gbScript, i ), k ), m ), 1 )
)
);,
myHead = Head Name( Arg( Arg( gbScript, i ), k ) );
Contains( {"Group X", "Group Y", "Wrap"}, myHead );,
//Print( "found group ", k );
Insert Into( LineScan:myGroups, Arg( Arg( Arg( gbScript, i ), k ), 1 ) )
),
);
)
);
foundX * foundY * foundCol;
);
LineScan:LS_sel_rows = Function( {},
failed = 0;
xx = xVar << get values();
yy = yVar << get values();
nr = N Items( yy );
x1 = LineScan:startx;
x2 = LineScan:exx;
y1 = LineScan:starty;
y2 = LineScan:exy;
dx = x2 - x1;
dy = y2 - y1;
d1_2sq=( dx * dx + dy * dy );
d1_2= Sqrt(d1_2sq);// distance between points
If( And( dx == 0, dy == 0 ),
Print( "no line" );
failed = 1;
,
px1 = (xx - x1);
py1 = (yy - y1);
dotp1 = (px1 * dx + py1 * dy);
proj1sq = dotp1 dotp1 / d1_2sq; // projection along the line
proj1=sqrt(proj1sq);
lensq = px1 px1 + py1 py1; // distance to pt1
dist = Sqrt( lensq - proj1sq ); //Pythagoras
selection = J( nr, 1 );
width = If( Is Empty( widthEB ),
Print( "use default" );
0.7;
,
widthEB << get()
);
selection[Loc( dist > width )] = .;
px2 = (xx - x2);
py2 = (yy - y2);
dotp2 = (px2 * dx + py2 * dy);
proj2sq = dotp2 dotp2 / d1_2sq;
proj2=sqrt(proj2sq);
selection[Loc( proj1 > d1_2 )] = .; //remove points too far away (radius aound start and end)
selection[Loc( proj2 > d1_2 )] = .;
filteredRows = Loc((1::nr)`);
Try(
ldf = Linescan:TheReport["Local Data Filter"] << get scriptable object(); // wonderful (thank you Jim)
filteredRows = ldf << Get Filtered Rows;
);
excludedRows = J( nr, 1 );
If(!IsMissing(filteredRows),
excludedRows[filteredRows] = .;
excludedRows=Loc(excludedRows);
selection[excludedRows] = .; //apply data filter
);
selection[LineScan:dt << Get Excluded Rows()] = .; // apply global data filter
selection = Loc( selection ); //just keep the non-empty ones
If( N Items( selection ) <= 0,
Print( "nothing selected" );
failed = 1;
,
posAlongLine = proj1[selection];
LineScan:CloseTemporaryTables();
LineScan:dt << Clear Select;
LineScan:dt << Select rows( selection );
LineScan:dt_tempLineCut = LineScan:dt << Subset( Invisible, Rows( selection ), Selected columns only( 0 ), hidden );
LineScan:dt_tempLineCut << New Column( "position along line", Numeric, "Continuous", values( posAlongLine ) );
LineScan:dt_tempLineCut << Set Name( "tempDTLineCutXY" );
);
);
Not( failed );
);
LineScan:GetStatisticsFunction = Function( {myStat},
Print( "implement" )
);
LineScan:LS_prepareExpressions = Function( {myStat},
//Print( "LS: prepareExpressions" );
myStatisticsFunction = Match( myStat,
"N", Name Expr( Col Number ),
"Mean", Name Expr( Col Mean ),
"Mode", Name Expr( Col Mode ),
"Sum", Name Expr( Col Sum ),
"Std Dev", Name Expr( Col Std Dev ),
"Min", Name Expr( Col Minimum ),
"Max", Name Expr( Col Maximum ),
"Median", Name Expr( Col Median ),
"Range", Name Expr( Col Range ),
"Cumulative Sum", Name Expr( Col Cumulative Sum ),
Name Expr( Col Number )
);
LineScan:YvariableName = myStat || "(" || (colVar << Get Name) || ")";
LineScan:preparedYFunction = Substitute(
Expr(
__aggregation__( __colVar__, __xVar__, __yVar__ )
),
Expr( __aggregation__ ), Name Expr( myStatisticsFunction ),
Expr( __colVar__ ), Name Expr( colVar ),
Expr( __xVar__ ), Name Expr( xVar ),
Expr( __yVar__ ), Name Expr( yVar ),
);
If( myStat == "Median",
LineScan:preparedYFunction = Insert( Name Expr( LineScan:preparedYFunction ), 0.5, 2 )
);
For Each( {GroupVar, idx}, LineScan:myGroups,
LineScan:preparedYFunction = Insert( Name Expr( LineScan:preparedYFunction ), Name Expr( GroupVar ) )
);
LineScan:preparedVariables = Expr(
Variables( X( :position along line ), Y( :YVariable ) )
);
If( N Items( LineScan:myGroups ),
LineScan:preparedVariables = Insert( Name Expr( LineScan:preparedVariables ), Eval Expr( Overlay( Expr( LineScan:myGroups[1] ) ) ) )
);
1 //return value, don't delete !!!
;
);
LineScan:LS_prepareWindow = Function( {},
//Print( "LS: prepareWindow" );
If( Is Empty( LineScan:LinecutWindow ),
LineScan:LinecutWindow = New Window( "Linecut",
Show Menu( 0 ),
Show Toolbars( 0 ),
V List Box(
H List Box( Text Box( "width of the linecut: " ), widthEB = Number Edit Box( 0.6 ), Text Box( " update? -> draw a new line" ) ),
Spacer Box( size( 100, 0 ) ),
H List Box( Spacer Box( size( 0, 100 ) ), gb2_container = V List Box() )
),
);
LineScan:LinecutWindow << on Close( // doesn't work ?!??!
Print( "closing window" );
LineScan:CloseTemporaryTables();
)
;
,
LineScan:LineCutWindow << Bring Window To Front
)
);
LineScan:LS_generateNewPlot = Function( {},
//Print( "generatePlot" );
Try( gbLC << delete() );
gb2_container << Append(
Eval(
Substitute(
Expr(
gbLC = LineScan:dt_tempLineCut << Graph Builder(
Transform Column( "YVariable", Formula( __statistics__ ) ),
Size( 450, 250 ),
Show Control Panel( 0 ),
Show Legend( 0 ),
Show Title( 0 ),
Fit Window(),
Graph Spacing( 4 ),
__variables__,
Elements( Points( X, Y, Legend( 3 ) ), Smoother( X, Y, Legend( 4 ), Lambda( 0.005 ) ) )
)
),
Expr( __statistics__ ), Name Expr( LineScan:preparedYFunction ),
Expr( __variables__ ), Name Expr( LineScan:preparedVariables )
)
)
);
If( N Items( LineScan:myGroups ),
gbLC << Show Legend( 1 )
);
Report( gbLC )[AxisBox( 1 )] << Min( 0 );
Report( gbLC )[Text Edit Box( 4 )] << Set Text( LineScan:YvariableName );
Report( gbLC )[Outline Box( 1 )] << Set Title( "Linecut" );
);
LineScan:LS_update = Function( {},
{Default Local},
//Print( "LS: update" );
If( LineScan:LS_findVariables(),
If( LineScan:LS_sel_rows(),
LineScan:LS_prepareExpressions( Linescan:myStatistics );
LineScan:LS_prepareWindow();
LineScan:LS_generateNewPlot();
)
)
);
LineScan:LS_getMousetrapCoordinates = Function( {},
If( LineScan:MyfirstClick == 1,
LineScan:dt << Clear Select;
LineScan:startx = x;
LineScan:starty = y;
LineScan:MyfirstClick++;
);
LineScan:exx = x;
LineScan:exy = y;
);
// now let's add the MouseTrap
LineScan:LS_Initialize();
Try(
LineScan:CloseTemporaryTables();
Linescan:TheReport = Current Report();
gbrs = (Current Report() << XPath( "//OutlineBox[@helpKey = 'Graph Builder']" ));
If( N Items( gbrs ),
Linescan:gb = gbrs[1] << Get Scriptable Object();
Linescan:dt = Linescan:gb << Get Data Table();
FrameBoxes = gbrs[1] << XPath( "//FrameBox" );
For Each( {myFrameBox, idx}, FrameBoxes,
myFrameBox << add graphics script(
Mousetrap(
LineScan:LS_getMousetrapCoordinates(),
LineScan:MyfirstClick = 1;
LineScan:mouse_released = 1;
);
myline = Line( {LineScan:startx, LineScan:starty}, {LineScan:exx, LineScan:exy} );
If( LineScan:mouse_released,
If( 0,
Print( 1 ),
LineScan:LS_update()
)
);
LineScan:mouse_released = 0;
)
);
);
);
/*dt = Open( "$SAMPLE_STIPS/Wafer Stacked Small.jmp" );
dt << Graph Builder(
Size( 534, 464 ),
Show Control Panel( 0 ),
Graph Spacing( 4 ),
Variables( X( :X_Die ), Y( :Y_Die ), Wrap( :Lot, Levels per Row( 3 ) ), Color( :Defects, Summary Statistic( "Sum" ) ) ),
Elements( Heatmap( X, Y, Legend( 5 ) ) ),
SendToReport(
Dispatch( {}, "X_Die", ScaleBox, {Min( -22 ), Max( 22 ), Inc( 5 ), Minor Ticks( 4 )} ),
Dispatch( {}, "Y_Die", ScaleBox, {Min( -20 ), Max( 22 ), Inc( 5 ), Minor Ticks( 4 )} ),
)
);*/
// second part --------------------------------------------------------
//Names Default To Here( 1 );
New Namespace(
"LineScan"
);
LineScan:LS_Initialize = Function( {}, // variables used for communication between the Linescan and the Mousetrap
LineScan:MyfirstClick = 1;
LineScan:startx = 0;
LineScan:starty = 0;
LineScan:exx = 0;
LineScan:exy = 0;
LineScan:mouse_released = 0;
LineScan:gb = 1;
LineScan:dt = 1;
);
LineScan:CloseTemporaryTables() = Function( {},
dtList = Get Data Table List();
For Each( {checkDt, idx}, dtList,
If( Not(IsMissing(Regex( checkDt << get name(), "tempDTLineCutXY.*" ))) ,
Print( checkDt << get name() || ": close" );
Close( checkDt, no save )
)
);
);
LineScan:LS_findVariables = Function( {},
foundX = 0;
foundY = 0;
foundCol = 0;
allVariables = (LineScan:gb << get variables);
For Each( {var, idx}, allVariables,
If( Arg( var[2] ) == "X",
xVar = var[1];
foundX = 1;
);
If( Arg( var[2] ) == "Y",
yVar = var[1];
foundY = 1;
);
If( Arg( var[2] ) == "Color",
colVar = var[1];
foundCol = 1;
);
);
LineScan:myStatistics = "Mean";
LineScan:myGroups = {};
gbScript = LineScan:gb << Get Script;
numArgs = N Arg( gbScript );
For( i = 1, i <= numArgs, i++,
If( Head Name( Arg( gbScript, i ) ) == "Variables",
//Print( "found variables", i );
nVariables = N Arg( Arg( gbScript, i ) );
For( k = 1, k <= nVariables, k++,
If(
Head Name( Arg( Arg( gbScript, i ), k ) ) == "Color",
//Print( "found color", k );
nEntries = N Arg( Arg( gbScript, i ) );
For( m = 1, m <= nEntries, m++,
If( Head Name( Arg( Arg( Arg( gbScript, i ), k ), m ) ) == "Summary Statistic",
//Print( "found stat", m );
LineScan:myStatistics = Arg( Arg( Arg( Arg( gbScript, i ), k ), m ), 1 )
)
);,
myHead = Head Name( Arg( Arg( gbScript, i ), k ) );
Contains( {"Group X", "Group Y", "Wrap"}, myHead );,
//Print( "found group ", k );
Insert Into( LineScan:myGroups, Arg( Arg( Arg( gbScript, i ), k ), 1 ) )
),
);
)
);
foundX * foundY * foundCol;
);
LineScan:LS_sel_rows = Function( {},
failed = 0;
xx = xVar << get values();
yy = yVar << get values();
nr = N Items( yy );
x1 = LineScan:startx;
x2 = LineScan:exx;
y1 = LineScan:starty;
y2 = LineScan:exy;
dx = x2 - x1;
dy = y2 - y1;
d1_2sq=( dx * dx + dy * dy );
d1_2= Sqrt(d1_2sq);// distance between points
If( And( dx == 0, dy == 0 ),
Print( "no line" );
failed = 1;
,
px1 = (xx - x1);
py1 = (yy - y1);
dotp1 = (px1 * dx + py1 * dy);
proj1sq = dotp1 dotp1 / d1_2sq; // projection along the line
proj1=sqrt(proj1sq);
lensq = px1 px1 + py1 py1; // distance to pt1
dist = Sqrt( lensq - proj1sq ); //Pythagoras
selection = J( nr, 1 );
width = If( Is Empty( widthEB ),
Print( "use default" );
0.7;
,
widthEB << get()
);
selection[Loc( dist > width )] = .;
px2 = (xx - x2);
py2 = (yy - y2);
dotp2 = (px2 * dx + py2 * dy);
proj2sq = dotp2 dotp2 / d1_2sq;
proj2=sqrt(proj2sq);
selection[Loc( proj1 > d1_2 )] = .; //remove points too far away (radius aound start and end)
selection[Loc( proj2 > d1_2 )] = .;
filteredRows = Loc((1::nr)`);
Try(
ldf = Linescan:TheReport["Local Data Filter"] << get scriptable object(); // wonderful (thank you Jim)
filteredRows = ldf << Get Filtered Rows;
);
excludedRows = J( nr, 1 );
If(!IsMissing(filteredRows),
excludedRows[filteredRows] = .;
excludedRows=Loc(excludedRows);
selection[excludedRows] = .; //apply data filter
);
selection[LineScan:dt << Get Excluded Rows()] = .; // apply global data filter
selection = Loc( selection ); //just keep the non-empty ones
If( N Items( selection ) <= 0,
Print( "nothing selected" );
failed = 1;
,
posAlongLine = proj1[selection];
LineScan:CloseTemporaryTables();
LineScan:dt << Clear Select;
LineScan:dt << Select rows( selection );
LineScan:dt_tempLineCut = LineScan:dt << Subset( Invisible, Rows( selection ), Selected columns only( 0 ), hidden );
LineScan:dt_tempLineCut << New Column( "position along line", Numeric, "Continuous", values( posAlongLine ) );
LineScan:dt_tempLineCut << Set Name( "tempDTLineCutXY" );
);
);
Not( failed );
);
LineScan:GetStatisticsFunction = Function( {myStat},
Print( "implement" )
);
LineScan:LS_prepareExpressions = Function( {myStat},
//Print( "LS: prepareExpressions" );
myStatisticsFunction = Match( myStat,
"N", Name Expr( Col Number ),
"Mean", Name Expr( Col Mean ),
"Mode", Name Expr( Col Mode ),
"Sum", Name Expr( Col Sum ),
"Std Dev", Name Expr( Col Std Dev ),
"Min", Name Expr( Col Minimum ),
"Max", Name Expr( Col Maximum ),
"Median", Name Expr( Col Median ),
"Range", Name Expr( Col Range ),
"Cumulative Sum", Name Expr( Col Cumulative Sum ),
Name Expr( Col Number )
);
LineScan:YvariableName = myStat || "(" || (colVar << Get Name) || ")";
LineScan:preparedYFunction = Substitute(
Expr(
__aggregation__( __colVar__, __xVar__, __yVar__ )
),
Expr( __aggregation__ ), Name Expr( myStatisticsFunction ),
Expr( __colVar__ ), Name Expr( colVar ),
Expr( __xVar__ ), Name Expr( xVar ),
Expr( __yVar__ ), Name Expr( yVar ),
);
If( myStat == "Median",
LineScan:preparedYFunction = Insert( Name Expr( LineScan:preparedYFunction ), 0.5, 2 )
);
For Each( {GroupVar, idx}, LineScan:myGroups,
LineScan:preparedYFunction = Insert( Name Expr( LineScan:preparedYFunction ), Name Expr( GroupVar ) )
);
LineScan:preparedVariables = Expr(
Variables( X( :position along line ), Y( :YVariable ) )
);
If( N Items( LineScan:myGroups ),
LineScan:preparedVariables = Insert( Name Expr( LineScan:preparedVariables ), Eval Expr( Overlay( Expr( LineScan:myGroups[1] ) ) ) )
);
1 //return value, don't delete !!!
;
);
LineScan:LS_prepareWindow = Function( {},
//Print( "LS: prepareWindow" );
If( Is Empty( LineScan:LinecutWindow ),
LineScan:LinecutWindow = New Window( "Linecut",
Show Menu( 0 ),
Show Toolbars( 0 ),
V List Box(
H List Box( Text Box( "width of the linecut: " ), widthEB = Number Edit Box( 0.6 ), Text Box( " update? -> draw a new line" ) ),
Spacer Box( size( 100, 0 ) ),
H List Box( Spacer Box( size( 0, 100 ) ), gb2_container = V List Box() )
),
);
LineScan:LinecutWindow << on Close( // doesn't work ?!??!
Print( "closing window" );
LineScan:CloseTemporaryTables();
)
;
,
LineScan:LineCutWindow << Bring Window To Front
)
);
LineScan:LS_generateNewPlot = Function( {},
//Print( "generatePlot" );
Try( gbLC << delete() );
gb2_container << Append(
Eval(
Substitute(
Expr(
gbLC = LineScan:dt_tempLineCut << Graph Builder(
Transform Column( "YVariable", Formula( __statistics__ ) ),
Size( 450, 250 ),
Show Control Panel( 0 ),
Show Legend( 0 ),
Show Title( 0 ),
Fit Window(),
Graph Spacing( 4 ),
__variables__,
Elements( Points( X, Y, Legend( 3 ) ), Smoother( X, Y, Legend( 4 ), Lambda( 0.005 ) ) )
)
),
Expr( __statistics__ ), Name Expr( LineScan:preparedYFunction ),
Expr( __variables__ ), Name Expr( LineScan:preparedVariables )
)
)
);
If( N Items( LineScan:myGroups ),
gbLC << Show Legend( 1 )
);
Report( gbLC )[AxisBox( 1 )] << Min( 0 );
Report( gbLC )[Text Edit Box( 4 )] << Set Text( LineScan:YvariableName );
Report( gbLC )[Outline Box( 1 )] << Set Title( "Linecut" );
);
LineScan:LS_update = Function( {},
{Default Local},
//Print( "LS: update" );
If( LineScan:LS_findVariables(),
If( LineScan:LS_sel_rows(),
LineScan:LS_prepareExpressions( Linescan:myStatistics );
LineScan:LS_prepareWindow();
LineScan:LS_generateNewPlot();
)
)
);
LineScan:LS_getMousetrapCoordinates = Function( {},
If( LineScan:MyfirstClick == 1,
LineScan:dt << Clear Select;
LineScan:startx = x;
LineScan:starty = y;
LineScan:MyfirstClick++;
);
LineScan:exx = x;
LineScan:exy = y;
);
// now let's add the MouseTrap
LineScan:LS_Initialize();
Try(
LineScan:CloseTemporaryTables();
Linescan:TheReport = Current Report();
gbrs = (Current Report() << XPath( "//OutlineBox[@helpKey = 'Graph Builder']" ));
If( N Items( gbrs ),
Linescan:gb = gbrs[1] << Get Scriptable Object();
Linescan:dt = Linescan:gb << Get Data Table();
FrameBoxes = gbrs[1] << XPath( "//FrameBox" );
For Each( {myFrameBox, idx}, FrameBoxes,
myFrameBox << add graphics script(
Mousetrap(
LineScan:LS_getMousetrapCoordinates(),
LineScan:MyfirstClick = 1;
LineScan:mouse_released = 1;
);
myline = Line( {LineScan:startx, LineScan:starty}, {LineScan:exx, LineScan:exy} );
If( LineScan:mouse_released,
If( 0,
Print( 1 ),
LineScan:LS_update()
)
);
LineScan:mouse_released = 0;
)
);
);
);