Bucle de ubicaciones x, y a lo largo del tiempoHola,
Soy bastante nuevo en jmp (actualmente estoy usando jmp 16) y tengo una pregunta sobre el siguiente escenario. Tengo un archivo csv que tiene las siguientes columnas para cada imperfección:
- Marca de tiempo, ID de serie, ubicación x, ubicación y, tamaño de la imperfección (en mm)
Trabajo con un proceso de limpieza y la herramienta de inspección proporciona información sobre cada imperfección del día. Hay un par de cosas que necesito rastrear:
1) número de veces que se ha procesado un ID de serie en particular y averiguar si es la primera vez que se ha limpiado, o la segunda, tercera, etc.
2) si la ID de serie se ha limpiado más de una vez, entonces necesito saber si alguna combinación de las ubicaciones (x, y) sigue en el mismo lugar después de cada limpieza
Graficando las ubicaciones xey y luego filtrando por tiempo pude llegar a responder 2) pero es un paso muy manual. Espero encontrar una solución usando jsl que pueda automatizar la información que necesito rastrear.
VentanasRe: bucle de ubicaciones x, y a lo largo del tiempo¿Qué tipo de resolución tienen las ubicaciones x, y? Por ejemplo, siempre pueden ser números enteros de 1 a 100, o pueden ser valores de punto flotante de 0 a 100 que se redondean al .01 más cercano o pueden ser flotantes sin límite aparente para la resolución. ¿Qué tan cerca tendría que estar el par x, y para que se repita? ¿El tamaño de la imperfección tiene algo que ver con la superposición x, y? ¿O el tamaño es siempre más pequeño que la cuadrícula x, y y se ignora?
Si solo hay 100 valores x y 100 y, y si el tamaño no es interesante, combinaría los valores xey en una sola clave, x * 100 + y quizás, que podría facilitar la prueba de repeticiones . Quizás lo mismo para los flotadores redondeados, hasta aproximadamente 6 dígitos significativos.
Pero si el tamaño importa, o las distancias tienen que ser probadas, podría usar una KDTable.
Además, ¿cuántas filas? menos de unos pocos miles probablemente no necesitarán ninguna optimización particular. Más de un millón probablemente necesitarán un algoritmo bien pensado. (Con menos de mil filas, cada fila puede pensar en cada otra fila y solo hay 1,000,000 de comparaciones, pero el doble del tamaño y las comparaciones se cuadruplican).
Re: bucle de ubicaciones x, y a lo largo del tiempoHola @SEG
1: intente utilizar la plataforma de resumen Table <<. allí, simplemente coloque el ID de serie, la ubicación xy la ubicación y en el grupo.
esto le dará una fila separada para cada combinación única de los tres.
Graficar esta nueva tabla de resumen sería útil, solo use la columna N como color o tamaño
2: una vez que produce un gráfico una vez, debajo del triángulo rojo en la parte superior izquierda, puede elegir guardar el script en la tabla de datos o en la ventana del script. jmp acaba de escribir el guión para ti.
si está utilizando jmp 16, haga clic en ver >> registro y obtendrá un script de todo lo que hizo en la sesión actual.
háganos saber si ayuda.
ron
Re: bucle de ubicaciones x, y a lo largo del tiempoHola,
¿Podría ayudarnos a comprender mejor su estructura de datos compartiendo un ejemplo (los datos simulados funcionarían bien)? Según su descripción, supongo que cada evento de limpieza es identificable por una combinación única de marca de tiempo e ID de serie. Además, ¿sus datos incluyen información replicada (es decir, filas con una combinación idéntica de marca de tiempo e ID de serie? Si lo hace, hará que el proceso sea más exigente. Finalmente, después de identificar múltiples eventos de limpieza para una ID de serie, ¿está interesado en capturar solo si las ubicaciones son idénticas en todos los eventos, idénticas entre dos eventos u otra cosa?
Mejor,
TS
Re: bucle de ubicaciones x, y a lo largo del tiempo
Hola craig
La ubicación xey salen 3 dígitos después del punto decimal. Siempre que estén dentro del 3% de la misma ubicación, se consideraría una imperfección repetida. El tamaño no tiene nada que ver con la superposición. Lo que se ha hecho en el pasado es que, una vez que se grafican, los primeros bucles se designan como un círculo en un color y los segundos obtienen una "x" en otro color. Una vez que se superponen, es visualmente fácil ver si está en la misma ubicación.
En términos de filas, podría llegar a varios miles dependiendo de cuánto se ejecute en un día. su nunca cruzó a millones, aunque es una posibilidad si miramos durante un período muy largo a la vez.
Re: bucle de ubicaciones x, y a lo largo del tiempoHola Thierry,
Adjunté una captura de pantalla de los datos simulados. como puede ver, cada ID obtendrá múltiples accesos al mismo sello de tiempo ya que todas las imperfecciones se escriben al mismo tiempo, la principal diferencia sería la ubicación x, y y el tamaño. También tenga en cuenta que este ejemplo es solo una primera limpieza. La segunda vez, la misma ID podría aparecer con más o menos filas y ahí es cuando me gustaría saber si se está repitiendo y también poder identificar que es un segundo, tercer, etc. bucles de limpieza.
Después de varias limpiezas para un numerador de serie, me gustaría capturar si las ubicaciones son idénticas en todos los eventos
Re: bucle de ubicaciones x, y a lo largo del tiempoAquí tienes un código de inicio. Deberá estudiarlo para asegurarse de que hace lo que espera. La salida está en la ventana Registro. (Adjuntaré un archivo. Es posible que el código siguiente esté estropeado porque el sitio web eliminó algunos "html no válidos". )
// 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 ) ) ) )
);