cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Choose Language Hide Translation Bar
Jackie_
Level VI

Select 2 rows

Hi JMP Community,

 

I want to highlight two data points from each X and Y coordinates of the failure bin "2". I tried to write a jsl code, but the results are not correct. 
The below code highlights more than two data points from X and Y coordinates of the failure bin "2". Any suggestions?

 

Here's the code

Names Default To Here( 1 );
dtt = Data Table( "failures" );
dt = Data Table( "Summary Bins" );
//Clear values
dt:Highlight[1 :: N Rows( dt )] = "";
//define list for storing +/-2 X and Y coord in the list
xList = [];
yList = [];

//get X and Y coord of the failing dies
fail_xcoord = dtt:X coord << get values;
fail_ycoord = dtt:Y coord << get values;

// Add and subtract 2 from X and Y using a loop
For( j = 1, j <= N Rows( dtt ), j++,
	For( i = -2, i <= 2, i++,
		newX = dtt:X coord[j] + i;
		newY = dtt:Y coord[j] + i;

		If( newX != dtt:X coord[j],
			Insert Into( xList, newX )
		); 
    

		If( newY != dtt:Y coord[j],
			Insert Into( yList, newY )
		);

    
	)
);

//Loop to highlight 2 dies
dt << Begin Data Update;
For( i = 1, i <= N Rows( dt ), i++,
	If( Contains( xlist, dt:X coord[i] ) & Contains( fail_ycoord, dt:Y coord[i] ),
		dt:Highlight[i] = "1";
		
		
	);
	If( Contains( ylist, dt:Y coord[i] ) & Contains( fail_xcoord, dt:X coord[i] ),
		dt:Highlight[i] = "1";
		
		
	);
		
);
dt << End Data Update;

dt << select where( :Highlight == "1" & :Bins == "1" );

 

Thanks, 
Jackie

2 ACCEPTED SOLUTIONS

Accepted Solutions
Craige_Hales
Super User

Re: Select 2 rows from failing die

Maybe something like this

dtt = Open( "/Z:/failures.jmp" );// 109 inner rows

expand = 2;// how far to look for a failure
// these are paired, keep them in a Nx2 matrix...
fail = (dtt:X coord << get values) || (dtt:Y coord << get values);
// get min and max of the matrix columns
failmin = V Min( fail );
failmax = V Max( fail );
// find the +/- 2 area of interest
colmin = failmin[1] - expand;
colmax = failmax[1] + expand;
rowmin = failmin[2] - expand;
rowmax = failmax[2] + expand;
// turn the failure list back into a rectangular matrix, mark the actual failures
unmarked = 0; // points that have not been marked yet
interior = 1; // the failures are interior points
border = 2; // the border points are near the failures
bigpatch = J( rowmax + 1, colmax + 1, unmarked );
For Each( {{r, c}}, across( fail[0, 2], fail[0, 1] ), bigpatch[r, c] = interior );
// helper to check near r,c
nearFailure = Function( {r0, c0}, //parameters
	{rlow, rhigh, clow, chigh, r, c}, // locals
	// low..high is expanded without going beyond the edge of bigpatch
	rlow = Max( 1, r0 - expand );
	rhigh = Min( N Rows( bigpatch ), r0 + expand );
	clow = Max( 1, c0 - expand );
	chigh = Min( N Cols( bigpatch ), c0 + expand );
	// rlow..chigh is a slightly expanded search area
	For( r = rlow, r <= rhigh, r += 1,
		For( c = clow, c <= chigh, c += 1, 
			// any interior point (1) nearby?
			If(
				bigpatch[r, c] == interior// uncomment for "rounder"				
//				& Sqrt( (r - r0) ^ 2 + (c - c0) ^ 2 ) <= expand// the diagonal distance of the corners is expand*1.414...nearly 3...
			,
				Return( 1 ) // found an interior point nearby
			)
		)
	);
	/*return*/	0; // no interior point found nearby
);

For( r = rowmin, r <= rowmax, r += 1,
	For( c = colmin, c <= colmax, c += 1,
		If( bigpatch[r, c] == unmarked & nearFailure( r, c ),
			bigpatch[r, c] = border// add a border to the bigpatch
		)
	)
);
// view a cellplot
dtcp = As Table( bigpatch[rowmin - 1 :: rowmax + 1, colmin - 1 :: colmax + 1] );
dtcp[1 :: N Rows( dtcp ), 0] = dtcp[N Rows( dtcp ) :: 1, 0];// flip to make the same as graph builder
dtcp << Cell Plot( Scale Uniformly( 0 ), Center at zero( 0 ), Y( dtcp << getcolumnnames ) );


dt = Open( "/Z:/Summary Bins.jmp" );// all rows
//Clear values
dt:Highlight[1 :: N Rows( dt )] = "";
//Loop to highlight 2 dies
dt << Begin Data Update;
For( i = 1, i <= N Rows( dt ), i++,
	c = dt:X coord[i];
	r = dt:Y coord[i];
	If( r < N Rows( bigpatch ) & c < N Cols( bigpatch ) & bigpatch[r, c] == border,
		dt:Highlight[i] = "1"
	);
);
dt << End Data Update;

dt << select where( :Highlight == "1" & :Bins == "1" );

dt << Graph Builder( Size( 528, 454 ), Show Control Panel( 0 ), Variables( X( :X coord ), Y( :Y coord ) ), Elements( Points( X, Y, Legend( 7 ) ) ) );

You might want this

capture4.png

 

or this, see the commented line for the distance calculation. Depends how you want to treat the diagonal distance.

capture2.png

 

 

 

 

 

Craige

View solution in original post

Craige_Hales
Super User

Re: Select 2 rows from failing die

this might work:

templatesize=15;
templateround = 1; // 0: square corners   1: round corners    2: diamond corners
templatelist = {};
for(x=-templatesize, x<=templatesize, x+=1,
	for(y=-templatesize, y<=templatesize, y+=1,
		if(templateround==0 // use all neighbor points
		| (templateround==1 & round(sqrt(x^2+y^2))<=templatesize) // use neighbors near or inside the circle
		| (templateround==2 & sqrt(x^2+y^2)<=templatesize) // use neighbors inside the circle
		,//
			templatelist[nitems(templatelist)+1] = evallist({x,y});
		)
	)
);
show(templatelist);
template = matrix(templatelist);
//astable(template)<<Graph Builder(
//	Variables( X( :Col2 ), Y( :Col1 ) ),
//	Elements( Points( X, Y, Legend( 3 ) ), Smoother( X, Y, Legend( 4 ) ) )
//);

capture.png

 

Craige

View solution in original post

9 REPLIES 9
Craige_Hales
Super User

Re: Select 2 rows from failing die

Maybe something like this

dtt = Open( "/Z:/failures.jmp" );// 109 inner rows

expand = 2;// how far to look for a failure
// these are paired, keep them in a Nx2 matrix...
fail = (dtt:X coord << get values) || (dtt:Y coord << get values);
// get min and max of the matrix columns
failmin = V Min( fail );
failmax = V Max( fail );
// find the +/- 2 area of interest
colmin = failmin[1] - expand;
colmax = failmax[1] + expand;
rowmin = failmin[2] - expand;
rowmax = failmax[2] + expand;
// turn the failure list back into a rectangular matrix, mark the actual failures
unmarked = 0; // points that have not been marked yet
interior = 1; // the failures are interior points
border = 2; // the border points are near the failures
bigpatch = J( rowmax + 1, colmax + 1, unmarked );
For Each( {{r, c}}, across( fail[0, 2], fail[0, 1] ), bigpatch[r, c] = interior );
// helper to check near r,c
nearFailure = Function( {r0, c0}, //parameters
	{rlow, rhigh, clow, chigh, r, c}, // locals
	// low..high is expanded without going beyond the edge of bigpatch
	rlow = Max( 1, r0 - expand );
	rhigh = Min( N Rows( bigpatch ), r0 + expand );
	clow = Max( 1, c0 - expand );
	chigh = Min( N Cols( bigpatch ), c0 + expand );
	// rlow..chigh is a slightly expanded search area
	For( r = rlow, r <= rhigh, r += 1,
		For( c = clow, c <= chigh, c += 1, 
			// any interior point (1) nearby?
			If(
				bigpatch[r, c] == interior// uncomment for "rounder"				
//				& Sqrt( (r - r0) ^ 2 + (c - c0) ^ 2 ) <= expand// the diagonal distance of the corners is expand*1.414...nearly 3...
			,
				Return( 1 ) // found an interior point nearby
			)
		)
	);
	/*return*/	0; // no interior point found nearby
);

For( r = rowmin, r <= rowmax, r += 1,
	For( c = colmin, c <= colmax, c += 1,
		If( bigpatch[r, c] == unmarked & nearFailure( r, c ),
			bigpatch[r, c] = border// add a border to the bigpatch
		)
	)
);
// view a cellplot
dtcp = As Table( bigpatch[rowmin - 1 :: rowmax + 1, colmin - 1 :: colmax + 1] );
dtcp[1 :: N Rows( dtcp ), 0] = dtcp[N Rows( dtcp ) :: 1, 0];// flip to make the same as graph builder
dtcp << Cell Plot( Scale Uniformly( 0 ), Center at zero( 0 ), Y( dtcp << getcolumnnames ) );


dt = Open( "/Z:/Summary Bins.jmp" );// all rows
//Clear values
dt:Highlight[1 :: N Rows( dt )] = "";
//Loop to highlight 2 dies
dt << Begin Data Update;
For( i = 1, i <= N Rows( dt ), i++,
	c = dt:X coord[i];
	r = dt:Y coord[i];
	If( r < N Rows( bigpatch ) & c < N Cols( bigpatch ) & bigpatch[r, c] == border,
		dt:Highlight[i] = "1"
	);
);
dt << End Data Update;

dt << select where( :Highlight == "1" & :Bins == "1" );

dt << Graph Builder( Size( 528, 454 ), Show Control Panel( 0 ), Variables( X( :X coord ), Y( :Y coord ) ), Elements( Points( X, Y, Legend( 7 ) ) ) );

You might want this

capture4.png

 

or this, see the commented line for the distance calculation. Depends how you want to treat the diagonal distance.

capture2.png

 

 

 

 

 

Craige
Jackie_
Level VI

Re: Select 2 rows from failing die

Thanks a lot Craige 

Jackie_
Level VI

Re: Select 2 rows from failing die

1

 

 

Craige_Hales
Super User

Re: Select 2 rows from failing die

I'm sure I've forgotten the bigger picture, but this bit

dtt = Open( "/Z:/failures.jmp" );// 109 inner rows

expand = 2;// how far to look for a failure
// these are paired, keep them in a Nx2 matrix...
fail = (dtt:X coord << get values) || (dtt:Y coord << get values);
// get min and max of the matrix columns
failmin = V Min( fail );
failmax = V Max( fail );
// find the +/- 2 area of interest
colmin = failmin[1] - expand;
colmax = failmax[1] + expand;
rowmin = failmin[2] - expand;
rowmax = failmax[2] + expand;

is identifying a containing rectangle about the points in the failures table. Fail is a 2-D matrix of 2 columns by N rows. failmin and failmax are each 2-element matrices with the minX,minY or maxX,maxY values.

colmin...rowmax are expanded by expand, because, as I recall, some part of the rest of the code needed to peek a bit further out of the rectangle. bigpatch is allocated that big. (bigpatch actually starts at the 1,1 origin.)

 

So I don't think abs() is what you want to do. I don't understand what you mean about selecting 2 dies from the failing region. Are you wanting to make the selected area inflated a bit more, fatter, with a two-die thicker border? Or are you wanting to identify two of the dies? I'm guessing you want a thicker border; I think that is what the nearFailure() function is doing...checking in the expand region to see if there is a nearby failure.

 

It looks like maybe you just need to make expand be bigger, say 3 or 4 instead of 2. Note the "rounder" comment as well; it might make sense to use that radius calculation for larger expand values.

edit:

@Jackie_ OK, the JSL does not work correctly with coordinates smaller than 3 because the 'bigpatch' matrix has no way to handle them.

There are two (maybe three) ways to fix it.

1) in both of the input tables, add a constant to all the Ys (and Xs if needed) so the smallest value is 3 or more.

or

2) rework the bigpatch matrix so its extent is max-min in both dimensions and so the indexing includes the offset.

 

disadvantage to 1 is the graphs will be labeled with the constant offset. -60 will become 3.

disadvantage to 2 is it is a moderately tricky change.

 

3) You might know why the numbers are negative (actually < 3) and have another way to work-around the problem.

Craige
Jackie_
Level VI

Re: Select 2 rows from failing die

.

 

Jackie_
Level VI

Re: Select 2 rows from failing die

I think Option 2 would make more sense. I would appreciate if you could share the modified matrix logic for big patch. I'm not exactly sure how to use fix this

Craige_Hales
Super User

Re: Select 2 rows from failing die

You might try something like this. It is a better approach, I think, but will probably have its own set of problems, so test carefully.

// all new code, all new bugs, check carefully to see if this does what you want

dtt = Open( "/Z:/failures(2).jmp" );
dtS = Open( "/Z:/Summary Bins(2).jmp" );

// the X-Y die coordinates are expected to be integers between -9,999,996 and +9,999,996
encodeLimit = 1e7; // pack/unpack two signed 7-digit integers in one 14-digit number

// a "key" is an X-Y pair packed into a single number. It is called a key
// because it is used as a key in an associative array. These next two
// routines convert between the two representations

keysToXY = Function( {keys},
	{x, y},
	x = Round( keys / encodeLimit );
	y = keys - x * encodeLimit;
	x || y;
);

XYtoKeys = Function( {xy},
	xy[0, 1] * encodeLimit + xy[0, 2]
);

// load the X-Y pairs that describe failure positions
failXY = dtt[0, {x coord, y coord}];
// elementary sanity checks
If( Any( failXY <= -encodeLimit + 4 ) | Any( failXY >= encodeLimit - 4 ),
	Throw( "data range" )
);
If( Any( failXY != Floor( failXY ) ),
	Throw( "integer coords" )
);

// convert X-Y failure locations to keys, verify they convert back again
failkeys = XYtoKeys( failXY );
If( !All( keysToXY( failkeys ) == failXY ),
	Throw( "encode/decode 1" )
);

// template for nearby points. THIS TABLE ENCODES THE 2 PIXEL BORDER.
// you might, or might not, want the corners included; the corners are
// commented out because I like the rounded appearance better.
template = [
//-2 -2, // corner
-2 -1, 
-2 0, 
-2 1, 
//-2 2, // corner
-1 -2, 
-1 -1, 
-1 0, 
-1 1, 
-1 2, 
0 -2, 
0 -1, 
0 0, // center
0 1, 
0 2, 
1 -2, 
1 -1, 
1 0, 
1 1, 
1 2, 
// 2 -2, // corner
2 -1, 
2 0, 
2 1
//, 2 2 // corner
];
// convert the template X-Y pairs into keys, verify they convert back again
templatekeys = XYtoKeys( template );
If( !All( keysToXY( templatekeys ) == template ),
	Throw( "encode/decode 2" )
);

// somthing very cool is going to happen next: template keys will be added to a failure 
// key to get a set of keys around the failure key. The template, above, represents a
// square (with rounded corners) about an origin. Adding a failure key moves the
// origin to the X-Y failure point. All the nearby locations are then inserted into a
// collection (associative array) of points that are within 2 of a failure point.
// When done, the actual failure points are removed from the collection, leaving the
// collection as the 2-wide border.

// use AssociativeArray as a set to hold the key values;
// the nearbyPoint set gets populated with both the failure
// points AND the points that are nearby as identified by the template.
nearbyPoints = Associative Array();
For Each( {failkey}, failkeys,
	nearbykeys = failkey + templatekeys; // nearby is the same shape as template, but at failkey, not 0,0
	nearbyPoints << Insert( Associative Array( nearbykeys ) );
);
// now remove the set of points formed from all the failures...after this, 
// nearbypoints is the 2-cell boundary without the interior.
nearbyPoints << Remove( Associative Array( failkeys ) );

// now make a table for a plot. red are from the failures table, blue are the border.

border = keysToXY( Matrix( nearbypoints << getkeys ) ) || J( N Items( nearbypoints ), 1, 1 );
center = failXY || J( N Rows( failXY ), 1, 2 );
dtg = As Table( border |/ center, <<columnnames( {"x coord", "y coord", "highlight"} ) );
dtg << Graph Builder(
	Size( 1493, 888 ),
	Show Control Panel( 0 ),
	Variables( X( :x coord ), Y( :y coord ), Color( :highlight ) ),
	Elements( Points( X, Y, Legend( 8 ) ) ),
	SendToReport( Dispatch( {}, "Graph Builder", FrameBox, {Marker Size( 2 ), Marker Drawing Mode( "Normal" )} ) )
);

//////////////// check this carefully; I'm not at all sure it does what you want ///////////////
// I don't know what the summary bins represents or why it has the odd cut-out areas.

dtS << deletecolumns( highlight ); // remove the old highlight, replace with new
dtS << Update( With( dtg ), Match Columns( :X coord = :x coord, :Y coord = :y coord ) );
dtS:highlight << Set Modeling Type( "Ordinal" );
dtS << Select Where( :highlight == 1 ) << Markers( "Dot" );
dtS << Select Where( :highlight == 2 ) << Markers( "FilledCircle" );
dtS << clear select;

dtS << Graph Builder(
	Size( 875, 811 ),
	Show Control Panel( 0 ),
	Variables( X( :X coord ), Y( :Y coord ), Color( :highlight ) ),
	Elements( Points( X, Y, Legend( 7 ) ) ),
	SendToReport(
		Dispatch( {}, "X coord", ScaleBox, {Format( "Best", 12 )} ),
		Dispatch( {}, "Y coord", ScaleBox, {Format( "Best", 12 )} ),
		Dispatch( {}, "400", ScaleBox,
			{Legend Model(
				7,
				Properties( -1, {gradient( {Color Theme( "Green to Black to Red" )} )}, Item ID( "highlight", 1 ) ),
				Properties( -1, {Line Color( -58112 ), Fill Color( -58112 )}, Item ID( "Y coord", 1 ) )
			)}
		),
		Dispatch( {}, "Graph Builder", FrameBox, {Marker Size( 1 ), Marker Drawing Mode( "Normal" )} )
	)
);

capture.png

Craige
Jackie_
Level VI

Re: Select 2 rows from failing die


You made my life easier. Thanks a lot, Craige!

 

Craige_Hales
Super User

Re: Select 2 rows from failing die

this might work:

templatesize=15;
templateround = 1; // 0: square corners   1: round corners    2: diamond corners
templatelist = {};
for(x=-templatesize, x<=templatesize, x+=1,
	for(y=-templatesize, y<=templatesize, y+=1,
		if(templateround==0 // use all neighbor points
		| (templateround==1 & round(sqrt(x^2+y^2))<=templatesize) // use neighbors near or inside the circle
		| (templateround==2 & sqrt(x^2+y^2)<=templatesize) // use neighbors inside the circle
		,//
			templatelist[nitems(templatelist)+1] = evallist({x,y});
		)
	)
);
show(templatelist);
template = matrix(templatelist);
//astable(template)<<Graph Builder(
//	Variables( X( :Col2 ), Y( :Col1 ) ),
//	Elements( Points( X, Y, Legend( 3 ) ), Smoother( X, Y, Legend( 4 ) ) )
//);

capture.png

 

Craige