안녕하십니까,
저는 jmp(현재 jmp 16 사용)를 처음 접했고 다음 시나리오에 대해 질문이 있습니다. 각 불완전성에 대해 다음 열이 있는 csv 파일이 있습니다.
- 타임스탬프, 일련 ID, x 위치, y 위치, 결함 크기(mm)
나는 청소 프로세스를 가지고 일하고 검사 도구는 하루의 모든 결함에 대한 정보를 제공합니다. 추적해야 할 몇 가지 사항이 있습니다.
1) 특정 일련 ID가 처리된 횟수 및 첫 번째 청소인지 또는 두 번째, 세 번째 등인지 확인
2) 일련 ID가 두 번 이상 청소된 경우 각 청소 후에 (x,y) 위치 조합이 여전히 동일한 위치에 있는지 알아야 합니다.
x 및 y 위치를 그래프로 그린 다음 시간별로 필터링하면 2)에 답할 수 있지만 매우 수동적인 단계입니다. 추적해야 하는 정보를 자동화할 수 있는 jsl을 사용하여 솔루션을 찾고 싶습니다.
x,y 위치에 어떤 종류의 해상도가 있습니까? 예를 들어, 항상 1에서 100 사이의 정수이거나 가장 가까운 .01로 반올림되는 0에서 100 사이의 부동 소수점 값이거나 해상도에 대한 명백한 제한이 없는 부동 소수점일 수 있습니다. 반복이 되려면 x,y 쌍이 얼마나 가까워야 합니까? 결함의 크기가 x,y 겹침과 관련이 있습니까? 아니면 크기가 항상 x, y 그리드보다 작고 무시됩니까?
100 x 및 100 y 값만 있고 크기가 흥미롭지 않은 경우 x 및 y 값을 단일 키, x*100+y로 결합하여 반복 테스트를 더 쉽게 만들 수 있습니다. . 최대 6개의 유효 자릿수까지 반올림된 부동 소수점에 대해서도 동일할 수 있습니다.
그러나 크기가 중요하거나 거리를 테스트해야 하는 경우 KDTable을 사용할 수 있습니다.
또한 행은 몇 개입니까? 수천 미만은 아마도 특정 최적화가 필요하지 않을 것입니다. 백만 명 이상이 아마도 잘 생각한 알고리즘이 필요할 것입니다. (1,000개 미만의 행에서 모든 행은 다른 모든 행에 대해 생각할 수 있고 1,000,000개의 비교만 있지만 크기는 두 배이고 비교는 4배입니다.)
안녕하세요 @SEG
1: Table << 요약 플랫폼을 사용해 보십시오. 거기에 그룹의 일련 ID, x 위치 및 y 위치를 입력하십시오.
이렇게 하면 세 가지 고유한 조합 각각에 대해 별도의 행이 제공됩니다.
이 새로운 요약 표를 그래프로 나타내면 유용할 것입니다. N 열을 색상이나 크기로 사용하기만 하면 됩니다.
2: 그래프를 한 번 생성하면 왼쪽 상단의 빨간색 삼각형 아래에서 스크립트를 데이터 테이블 또는 스크립트 창에 저장하도록 선택할 수 있습니다. jmp가 방금 스크립트를 작성했습니다.
jmp 16을 사용하는 경우 보기 >> 로그를 클릭하면 현재 세션에서 수행한 모든 작업에 대한 스크립트가 표시됩니다.
도움이 되는지 알려주세요.
론
안녕하세요,
예제를 공유하여 데이터 구조를 더 잘 이해하는 데 도움을 주시겠습니까(모의 데이터는 잘 작동함)? 귀하의 설명에 따르면 각 청소 이벤트는 타임스탬프와 일련 ID의 고유한 조합으로 식별할 수 있다고 생각합니다. 또한 데이터에 복제 정보가 포함되어 있습니까(예: Timestamp와 일련 ID의 조합이 동일한 행이 있습니까? 그렇다면 프로세스가 더 까다로워집니다. 마지막으로 일련 ID에 대한 여러 정리 이벤트를 식별한 후 위치가 모든 이벤트에서 동일하거나 두 이벤트 간에 동일한 경우에만 캡처하는 데 관심이 있습니까?
최상의,
TS
안녕하세요 크레이그
x 및 y 위치는 소수점 이하 3자리로 나옵니다. 동일한 위치의 3% 이내에 있는 한 반복적인 불완전으로 간주됩니다. 크기는 중첩과 관련이 없습니다. 과거에 수행된 작업은 그래프로 표시된 첫 번째 루프가 한 색상의 원으로 지정되고 두 번째 루프가 다른 색상의 "x"를 얻는 것입니다. 겹치면 시각적으로 쉽게 같은 위치에 있는지 확인할 수 있습니다.
행의 측면에서 하루에 실행되는 양에 따라 수천 개가 될 수 있습니다. 우리가 한 번에 매우 긴 기간 동안 볼 경우 가능성이 있지만 수백만으로 넘어간 적은 없습니다.
안녕하세요 티에리입니다.
모의 데이터의 스크린샷을 첨부했습니다. 보시다시피, 각 ID는 모든 결함이 동시에 작성되므로 동일한 타임 스탬프에 여러 히트를 얻습니다. 주요 차이점은 x, y 위치 및 크기입니다. 또한 이 예는 처음 청소하는 경우에만 해당됩니다. 두 번째로 동일한 ID가 더 많거나 적은 행과 함께 나타날 수 있으며 반복되는지 찾고 싶을 때 두 번째, 세 번째 등의 청소 루프를 식별할 수 있습니다.
일련 번호에 대해 여러 번 청소한 후 모든 이벤트에서 위치가 동일한지 캡처하고 싶습니다.
다음은 시작 코드입니다. 당신은 그것이 당신이 기대하는 것을 수행하는지 확인하기 위해 그것을 연구해야 할 것입니다. 출력은 로그 창에 있습니다. (파일을 첨부하겠습니다. 웹 사이트에서 일부 "잘못된 html"을 제거했기 때문에 아래 코드가 엉망일 수 있습니다. )
// synthesize some data
radius = 1;
dt = New Table( "Untitled",
Add Rows( 1000 ), // <<<<<<<<<<<<<< change number of rows here
New Column( "time", Numeric, "Continuous", Format( "Best", 12 ) ),
New Column( "waferID", Numeric, "Continuous", Format( "Best", 12 ) ),
New Column( "xLocation", Numeric, "Continuous", Format( "Best", 12 ) ),
New Column( "yLocation", Numeric, "Continuous", Format( "Best", 12 ) )
);
here:time = 0; // for this synth data, time just increments by 1
here:waferID = 0; // and the waferID is random 0-9
For( row = 1, row <= N Rows( dt ), row += 1,
If( Random Uniform() > .8, // determines how many points in a cleaning, before time changes and wafer re-randomizes
here:time += 1;
here:waferID = Random Integer( 0, 9 );
);
dt:time[row] = here:time;
dt:waferID[row] = here:waferID;
dt:xLocation[row] = Round( Random Uniform( -radius, radius ), 2 );
dt:yLocation[row] = Round( Random Uniform( -radius, radius ), 2 );
);
// find the unique waferIDs using summary
dtWafer = dt << Summary( Group( :waferID ), Link to original data table( 1 ) );
dtWaferTime = dt << Summary( Group( :waferID, :time ) );
dtNWafer = dtWaferTime << Summary( Group( :waferID ) ); //number of distinct times for this wafer is number of cleanings
close = .03; // <<< this determines how close makes a hit
// produce a report for each waferID that shows up in the cleaning data...
For( iWafer = 1, iWafer <= N Rows( dtWafer ), iWafer += 1,
dtWafer << clear select << selectrows( iWafer ); // dtWafer selection also selects rows in dt because linked
rows = dt << get selected rows; // all the rows for this wafer, across all times
// rows is a 1-column matrix of row numbers in dt for this wafer. the argument to KDTable
// is all the locations over all cleanings for this wafer.
kdt = KDTable( dt[rows, {xLocation, yLocation}] );
// report header for each waferID... the report might have no lines below the header, or a bunch... Not indented.
Write( Eval Insert( "\!n\!nprocessing waferID=^dtWafer:waferID[iWafer]^, ^nrows(rows)^ points during ^dtNWafer:nrows[iWafer]^ cleanings" ) );
For( irow = 1, irow <= N Rows( rows ), irow += 1, // the rows should be ascending time
row = rows[irow]; // row (singular) is an index to dt
// find rows {up to this many,up to this far} near irow
{index, distance} = kdt << kNearestRows( {dtWafer:NRows[iWafer], close}, irow );
// above, index is into the 1-column matrix of row numbers. below, it becomes index into dt
index = rows[index];
printedHeader = 0; // don't print this header unless there are duplicates to go with it
// distance[] and index[] have same number of rows; index is indexes to near neighbors and distance is to the neighbor
For( idistance = 1, idistance <= N Items( distance ), idistance += 1,
If( dt:waferID[index[idistance]] != dt:waferID[row] | dt:waferID[row] != dtWafer:waferID[iWafer],
Throw( "wafer mismatch" )
);// sanity check
If( distance[idistance] <= close, // typically there is one item with a bigger distance than we care about, must be ignored by else-break below.
If( !printedHeader, // a little indented...
Write(
Eval Insert(
"\!n matches for row ^row^ time ^dt:time[row]^ loc [^char(dt:xLocation[row],7,3)^,^char(dt:yLocation[row],7,3)^]"
)
);
printedHeader = 1;
);
// there can be more than one subsequent cleaning, indented more...
Write( Eval Insert( "\!n row ^index[idistance]^ time ^dt:time[index[idistance]]^ " ) );
Write( Eval Insert( "[^char(dt:xLocation[index[idistance]],7,3)^,^char(dt:yLocation[index[idistance]],7,3)^]) " ) );
Write( Eval Insert( "dist(^distance[idistance]^)" ) );
, //else
Break()
);
);
kdt << removerows( irow ); // never look back at this row from future rows
);
);
// a graph to examine the rows found to be close.
dt << Graph Builder(
Size( 867, 787 ),
Show Control Panel( 0 ),
Variables( X( :xLocation ), Y( :yLocation ) ),
Elements( Points( X, Y, Legend( 5 ) ) ),
Local Data Filter( Add Filter( columns( :waferID ), Modeling Type( :waferID, Nominal ), Display( :waferID, N Items( 14 ) ) ) )
);