こんにちは、
私はjmp(現在jmp 16を使用)にかなり慣れていないので、次のシナリオについて質問があります。 欠陥ごとに次の列があるcsvファイルがあります。
-タイムスタンプ、シリアルID、xの場所、yの場所、欠陥のサイズ(mm単位)
私はクリーニングプロセスを使用しており、検査ツールはその日のすべての欠陥に関する情報を提供します。 追跡する必要があることがいくつかあります。
1)特定のシリアルIDが処理された回数で、最初にクリーニングされたのか、2番目、3番目などであるかを確認します。
2)シリアルIDが複数回クリーニングされた場合、各クリーニング後に(x、y)の場所の組み合わせのいずれかがまだ同じ場所にあるかどうかを知る必要があります
xとyの位置をグラフ化し、時間でフィルタリングすると、2)に答えることができますが、これは非常に手動の手順です。 追跡する必要のある情報を自動化できるjslを使用したソリューションを見つけたいと思っています。
x、yの場所にはどのような解像度がありますか? たとえば、常に1から100までの整数であるか、最も近い.01に丸められる0から100までの浮動小数点値であるか、解像度に明らかな制限がない浮動小数点である可能性があります。 x、yペアがリピートになるにはどれくらい近くなければなりませんか? 欠陥のサイズは、x、yのオーバーラップと関係がありますか? または、サイズは常にx、yグリッドよりも小さく、無視されますか?
x値とy値が100個しかない場合で、サイズが面白くない場合は、x値とy値を1つのキー(おそらくx * 100 + y)に結合すると、繰り返しのテストが簡単になる可能性があります。 。 おそらく、丸みを帯びたフロートでも同じで、有効数字は最大約6桁です。
ただし、サイズが重要な場合、または距離をテストする必要がある場合は、KDTableを使用する場合があります。
また、何行ですか?おそらく数千未満は特定の最適化を必要としないでしょう。 100万を超える場合は、よく考えられたアルゴリズムが必要になるでしょう。 (1000行未満の場合、すべての行が1行おきに考えることができ、比較は1,000,000しかありませんが、サイズが2倍になり、比較が4倍になります。)
やあ@SEG
1:Table <<サマリープラットフォームを使用してみてください。そこで、シリアルID、xの場所、yの場所をグループに入れるだけです。
これにより、3つの固有の組み合わせごとに個別の行が表示されます。
この新しい要約テーブルをグラフ化すると便利です。色またはサイズとしてN列を使用するだけです。
2:グラフを一度作成すると、左上の赤い三角形の下で、スクリプトをデータテーブルまたはスクリプトウィンドウに保存することを選択できます。 jmpがスクリプトを作成しました。
jmp 16を使用している場合は、[表示] >> [ログ]をクリックすると、現在のセッションで行ったすべてのスクリプトが表示されます。
それが役立つかどうか私たちに知らせてください。
ロン
やあ、
例を共有して、データ構造をよりよく理解するのを手伝っていただけませんか(モックデータは正常に機能します)。 あなたの説明に基づいて、各クリーニングイベントはタイムスタンプとシリアルIDの一意の組み合わせによって識別できると思います。 また、データには複製情報(つまり、タイムスタンプとシリアルIDの同じ組み合わせの行)が含まれていますか? もしそうなら、それはプロセスをより要求の厳しいものにするでしょう。 最後に、シリアルIDの複数のクリーニングイベントを識別した後、場所がすべてのイベントで同一であるか、2つのイベント間で同一であるか、または他の何かである場合にのみキャプチャすることに関心がありますか?
一番、
NS
こんにちはクレイグ
xとyの位置は、小数点以下3桁になります。 それらが同じ場所の3%以内にある限り、それは繰り返しの不完全性と見なされます。 サイズはオーバーラップとは関係ありません。 過去に行われたことは、グラフ化されると、最初のループが1つの色の円として指定され、2番目のループが別の色の「x」を取得することです。 それらが重なると、同じ場所にあるかどうかを視覚的に簡単に確認できます。
行に関しては、1日の実行量によっては、数千に達する可能性があります。一度に非常に長い期間を見れば可能性はありますが、それは決して数百万に達することはありませんでした。
こんにちはティエリー、
模擬データのスクリーンショットを添付しました。ご覧のとおり、すべての欠陥が同時に書き込まれるため、各IDは同時に複数のヒットを取得します。主な違いは、x、yの位置とサイズです。 また、この例は初めてのクリーニングにすぎないことにも注意してください。 2回目は、同じIDが多かれ少なかれ行で表示される可能性があり、それが繰り返されているかどうかを確認し、2回目、3回目などのクリーニングのループを識別できるようにしたい場合です。
シリアル番号を複数回クリーニングした後、すべてのイベントで場所が同じであるかどうかをキャプチャしたいと思います
これがいくつかのスターターコードです。 あなたはそれがあなたが期待することをすることを確認するためにそれを研究する必要があるでしょう。 出力はログウィンドウにあります。 (ファイルを添付します。Webサイトで「無効な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 ) ) ) )
);