XY-Positionen im Zeitverlauf wiederholenHallo,
Ich bin ziemlich neu bei jmp (derzeit mit jmp 16) und habe eine Frage zu dem folgenden Szenario. Ich habe eine CSV-Datei mit den folgenden Spalten für jede Unvollkommenheit:
- Zeitstempel, Seriennummer, x-Position, y-Position, Größe der Fehlstelle (in mm)
Ich arbeite mit einem Reinigungsprozess und das Inspektionstool gibt Auskunft über jede einzelne Unvollkommenheit des Tages. Es gibt ein paar Dinge, die ich verfolgen muss:
1) wie oft eine bestimmte Seriennummer verarbeitet wurde und ob sie zum ersten Mal oder zum zweiten, dritten usw.
2) Wenn die Seriennummer mehr als einmal gereinigt wurde, muss ich nach jeder Reinigung wissen, ob sich eine der Kombinationen der (x, y)-Positionen noch an derselben Stelle befindet
Die x- und y-Positionen grafisch darzustellen und dann nach Zeit zu filtern, könnte ich beantworten 2), aber es ist ein sehr manueller Schritt. Ich hoffe, eine Lösung mit jsl zu finden, die die Informationen automatisieren könnte, die ich nachverfolgen muss.
FensterRe: XY-Positionen im Zeitverlauf wiederholenWelche Auflösung haben die XY-Positionen? Sie können beispielsweise immer ganze Zahlen von 1 bis 100 sein, oder es kann sich um Gleitkommawerte von 0 bis 100 handeln, die auf die nächsten 0,01 gerundet werden, oder um Gleitkommawerte ohne offensichtliche Begrenzung der Auflösung. Wie nah müsste das XY-Paar sein, um eine Wiederholung zu sein? Hat die Größe der Unvollkommenheit etwas mit der XY-Überlappung zu tun? Oder ist die Größe immer kleiner als das XY-Raster und wird ignoriert?
Wenn es nur 100 x- und 100 y-Werte gibt und die Größe nicht interessant ist, würde ich die x- und y-Werte in einem einzigen Schlüssel kombinieren, x*100+y vielleicht, das könnte das Testen auf Wiederholungen erleichtern . Vielleicht das gleiche für gerundete Gleitkommazahlen, bis zu etwa 6 signifikanten Stellen.
Aber wenn es auf die Größe ankommt oder die Abstände getestet werden müssen, kann ich eine KDTable verwenden.
Außerdem, wie viele Zeilen? weniger als ein paar Tausend benötigen wahrscheinlich keine besondere Optimierung. Mehr als eine Million werden wahrscheinlich einen gut durchdachten Algorithmus brauchen. (Bei weniger als tausend Zeilen kann jede Zeile an jede andere Zeile denken und es gibt nur 1.000.000 Vergleiche, aber die doppelte Größe und die Vergleiche vervierfachen sich.)
Re: XY-Positionen im Zeitverlauf wiederholenHi @SEG
1: Versuchen Sie es mit der Übersichtsplattform Tabelle <<. Geben Sie dort einfach Seriennummer, x-Standort und y-Standort in die Gruppe ein.
Dadurch erhalten Sie eine separate Zeile für jede einzigartige Kombination der drei.
Es wäre nützlich, diese neue Übersichtstabelle grafisch darzustellen, verwenden Sie einfach die Spalte N als Farbe oder Größe
2: Sobald Sie einmal ein Diagramm erstellt haben, können Sie unter dem roten Dreieck oben links wählen, ob Sie das Skript in der Datentabelle oder im Skriptfenster speichern möchten. jmp hat gerade das Skript für Sie geschrieben.
Wenn Sie jmp 16 verwenden, klicken Sie auf view>>log und Sie erhalten ein Skript von allem, was Sie in der aktuellen Sitzung getan haben.
lass es uns wissen, wenn es hilft.
ron
Re: XY-Positionen im Zeitverlauf wiederholenHi,
Könnten Sie uns helfen, Ihre Datenstruktur besser zu verstehen, indem Sie ein Beispiel teilen (Mock-Daten würden gut funktionieren)? Aufgrund Ihrer Beschreibung vermute ich, dass jedes Reinigungsereignis durch eine eindeutige Kombination aus Zeitstempel und Seriennummer identifizierbar ist. Enthalten Ihre Daten auch Replikatinformationen (dh Zeilen mit einer identischen Kombination aus Zeitstempel und Seriennummer? Wenn dies der Fall ist, wird der Prozess anspruchsvoller. Sind Sie schließlich daran interessiert, nach der Identifizierung mehrerer Reinigungsereignisse für eine Serien-ID nur zu erfassen, wenn die Standorte bei allen Ereignissen identisch sind, bei zwei beliebigen Ereignissen identisch sind oder etwas anderes?
Am besten,
TS
Re: XY-Positionen im Zeitverlauf wiederholen
Hallo Craig
Die x- und y-Position erlöschen 3 Stellen nach dem Komma. Solange sie sich innerhalb von 3% von derselben Stelle befinden, wird dies als wiederholte Unvollkommenheit angesehen. Die Größe hat nichts mit der Überlappung zu tun. Was in der Vergangenheit getan wurde, ist, dass die ersten Schleifen, sobald sie grafisch dargestellt sind, als Kreis in einer Farbe und die zweiten Schleifen als "x" in einer anderen Farbe bezeichnet werden. Sobald sie sich überlappen, ist es visuell leicht zu erkennen, ob sie sich an derselben Stelle befinden.
In Bezug auf die Zeilen könnte es in die mehrere Tausend gehen, je nachdem, wie viel an einem Tag ausgeführt wird. Es ist nie in Millionen gegangen, obwohl es eine Möglichkeit ist, wenn wir über einen sehr langen Zeitraum auf einmal schauen.
Re: XY-Positionen im Zeitverlauf wiederholenHallo Thierry,
Ich habe einen Screenshot der Mock-Daten angehängt. Wie Sie sehen, erhält jede ID mehrere Treffer gleichzeitig, da alle Unvollkommenheiten gleichzeitig geschrieben werden. Der Hauptunterschied wäre die XY-Position und die Größe. Beachten Sie auch, dass es sich bei diesem Beispiel nur um eine erstmalige Reinigung handelt. Beim zweiten Mal könnte dieselbe ID mit mehr oder weniger Zeilen erscheinen, und dann möchte ich herausfinden, ob sie sich wiederholt, und auch in der Lage sein, zu erkennen, dass es sich um eine zweite, dritte usw. Reinigungsschleife handelt.
Nach mehreren Bereinigungen für eine Seriennummer möchte ich erfassen, ob die Orte bei allen Veranstaltungen identisch sind
Re: XY-Positionen im Zeitverlauf wiederholenHier ist ein Startcode. Sie müssen es studieren, um sicherzustellen, dass es das tut, was Sie erwarten. Die Ausgabe erfolgt im Protokollfenster. (Ich hänge eine Datei an. Der unten stehende Code ist möglicherweise durcheinander, weil die Website "ungültiges HTML" entfernt hat. )
// 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 ) ) ) )
);