Optimizar el cálculoHola,
Tengo un código jsl para calcular la distancia radial desde el centro de la oblea. La tabla de datos XYCoord tiene columnas X, Y y el identificador de la oblea.
Calcula la distancia y agrega una columna de distancia de 1 mm desde el centro hasta la tabla.
Actualmente, con 656k filas, el proceso tarda más de 3 a 4 minutos en finalizar, lo cual es demasiado.
¿Hay alguna manera de optimizarlo y hacerlo más rápido?
Automatización y scriptingRe: Optimizar el cálculoIntenté ejecutar su secuencia de comandos con los datos que me proporcionó y falló. El primer elemento que intenté corregir fue un "=" extraviado en varias líneas de la secuencia de comandos.
Las líneas 23, 25, 106, 139 y 152 tenían un solo "=".
A continuación, los mensajes de error se convirtieron en lo que parecen ser columnas que aparentemente se están limpiando de ejecuciones anteriores, pero en la tabla que proporcionó no están allí, por lo que el script falla.
RadiusDieCenter, centrado en x, centrado en y, radio redondeado 1 mm, radio redondeado 0,51 mm
Agregué Try() alrededor de las líneas ofensivas
Se hace referencia a la columna X Coord en la línea 21 pero no existe en la tabla de datos
Lo cambié a U1_x asumiendo que es la columna de coordenadas x para la ejecución.
El código se ejecutó sin errores en 2 minutos y 12 segundos, pero no sé si los resultados son correctos. Las columnas Xcentering e Ycentering son todas ceros. ¿Es esto lo que se esperaba?

Re: Optimizar el cálculoHola Jim,
Sí, es correcto. Puedes verificar los resultados trazando el gráfico X e Y y resaltando los valores de columna de 1 mm. Me pregunto si esto se puede optimizar aún más. He corregido los errores en el archivo jsl adjunto anteriormente.
Re: Optimizar el cálculoHola @Jackie_ ,
El script recalculó varios valores de Col en cada bucle. Intente lo siguiente:
fin - inicio = 6.15000000002328;
Names Default To Here( 1 );
start = Tick Seconds();
dt = Current Data Table();
dt << Clear Column Selection;
Try( dt << delete columns( RadiusDieCenter ) );
Try(
dt << delete columns( RadiusDieEdge );
dt << delete columns( Xcentering );
dt << delete columns( Ycentering );
dt << delete columns( Radius Rounded 1mm );
dt << delete columns( Radius Rounded 0.51mm );
dt << delete columns( Radius Rounded 1mm );
);
z5Identifier = 1;
Xaxis = "U1_x";
Yaxis = "U1_y";
DieXSize = 1.160; //in mm
DieYSize = 0.810;//in mm
WaferColumns = N Items( Associative Array( As Column( Xaxis ) ) << Get Keys );
columnsRad = ((WaferColumns * DieXSize) / 2);
MaxRadiusEntry = 147;
dt << Set Table Variable( "DieXSize", DieXSize );
dt << Set Table Variable( "DieYSize", DieYSize );
dt << Set Table Variable( "MaxRadius", MaxRadiusEntry );
dt << begin data update;
xcoordmax = Col Maximum( As Column( Xaxis ) );
xcoordmin = Col Minimum( As Column( Xaxis ) );
ycoordmax = Col Maximum( As Column( Yaxis ) );
ycoordmin = Col Minimum( As Column( Yaxis ) );
New Column( "RadiusDieCenter",
Formula( Sqrt( (Abs( (As Column( Xaxis ) - CenterXCoord) * DieXSize )) ^ 2 + Abs( ((As Column( Yaxis ) - CenterYCoord) * DieYSize) ) ^ 2 ) )
);
New Column( "RadiusDieEdge",
Formula(
Sqrt(
(Abs( (As Column( Xaxis ) - CenterXCoord) * DieXSize ) + Abs( DieXSize / 2 )) ^ 2 + (Abs(
(As Column( Yaxis ) - CenterYCoord) * DieYSize
) + Abs( DieYSize / 2 )) ^ 2
)
)
);
xcoordrange = xcoordmax - xcoordmin;
ycoordrange = ycoordmax - ycoordmin;
dt << Set Table Variable( "CenterXCoord", xcoordmin + xcoordrange / 4 );
dt << Set Table Variable( "CenterYCoord", ycoordmin + ycoordrange / 4 );
dt << Run Formulas;
xiter = Ceiling( Log( xcoordrange * 1600, 1.8 ) );
yiter = Ceiling( Log( ycoordrange * 1600, 1.8 ) );
maxiter = Max( xiter, yiter );
New Column( "Xcentering",
Numeric,
Formula(
If( As Column( Xaxis ) > :CenterXCoord & :RadiusDieEdge > :MaxRadius,
1,
If( As Column( Xaxis ) < :CenterXCoord & :RadiusDieEdge > :MaxRadius,
-1,
0
)
)
)
);
New Column( "Ycentering",
Numeric,
Formula(
If( As Column( Yaxis ) > :CenterYCoord & :RadiusDieEdge > :MaxRadius,
1,
If( As Column( Yaxis ) < :CenterYCoord & :RadiusDieEdge > :MaxRadius,
-1,
0
)
)
)
);
dt << end data update;
sum_x_centering = Col Sum( :Xcentering );
min_x_centering = Col Min( :Xcentering );
max_x_centering = Col Max( :Xcentering );
sum_y_centering = Col Sum( :Ycentering );
min_y_centering = Col Min( :Ycentering );
max_y_centering = Col Max( :Ycentering );
For( i = 1, i <= maxiter, i++,
centerx = Num( dt << Get Table Variable( "CenterXCoord" ) );
centery = Num( dt << Get Table Variable( "CenterYCoord" ) );
xcoordrange = xcoordrange / 1.8;
ycoordrange = ycoordrange / 1.8;
dt << Run Formulas;
If( sum_x_centering > 0,
dt << Set Table Variable( "CenterXCoord", centerx + xcoordrange );
centerx = centerx + xcoordrange;
,
If( sum_x_centering < 0,
dt << Set Table Variable( "CenterXCoord", centerx - xcoordrange );
centerx = centerx + xcoordrange;
)
);
If( sum_y_centering > 0,
dt << Set Table Variable( "CenterYCoord", centery + ycoordrange );
centery = centery + ycoordrange;
,
If( sum_y_centering < 0,
dt << Set Table Variable( "CenterYCoord", centery - ycoordrange );
centery = centery + ycoordrange;
)
);
If( max_x_centering < 1 & min_x_centering > -1 & max_y_centering < 1 & min_y_centering > -1,
OldRadius = dt << Get Table Variable( "MaxRadius" );
NewRadius = Num( OldRadius ) - 0.01;
dt << Set Table Variable( "MaxRadius", Char( NewRadius ) );
xcoordrange = xcoordmax - xcoordmin;
ycoordrange = ycoordmax - ycoordmin;
dt << Run Formulas;
i = 1;
);
dt << Run Formulas;
);
New Column( "Radius Rounded 1mm", Numeric, "Continuous", Format( "Best", 12 ), Formula( Ceiling( :RadiusDieEdge ) ) );
end = Tick Seconds();
Show( end - start );
Re: Optimizar el cálculoLo que considero que se podría utilizar para acelerar el procesamiento es recodificar el script y eliminar el uso de scripts de tabla como almacenamiento intermedio.
Ejecuté una pequeña prueba para verificar la eficiencia de usar una variable de tabla versus una variable de memoria y, en mi prueba, el método de variable de tabla utilizó 26 segundos para procesarse, y el método de variable de memoria tomó 0,5 segundos.
Considere la posibilidad de utilizar una variable de memoria global o crear una variable de espacio de nombres para guardar los cálculos provisionales. Si desea que las variables de tabla tengan los valores finales, solo tiene que configurarlas una vez al final del script.
Re: Optimizar el cálculoEso es genial. ¿Te importaría compartirlo, Jim?
Re: Optimizar el cálculoLos resultados son incorrectos @robot

Debería estar con mi guión

Re: Optimizar el cálculoAquí están los 2 scripts de prueba que utilicé
names default to here(1);
dt = new table("example");
dt << new table variable("test",42);
start = tick seconds();
dt=current data table();
for(i=1,i<=1000000,i++,
x=num(dt<<GET table="" variable=""></GET>
<CODE class=" language-jsl">names default to here(1);
If(!isnamespace(t), t = new namespace("temp"));
start = tick seconds();
dt=current data table();
t:x=1;
for(i=1,i<=1000000,i++,
y = t:x;
y=y+1;
t:x=y;
);
end = tick seconds();
show(end -start);Re: Optimizar el cálculoMirando rápidamente el script, probablemente haya muchas optimizaciones diferentes que se pueden hacer, pero estoy un poco confundido sobre lo que estás calculando.
- ¿Cómo se determina el centro de la oblea a partir de estos datos?
- ¿Distancia desde el centro de la oblea a qué radio?
- ¿Todo el troquel tiene que pertenecer a los radios o solo al centro?
Re: Optimizar el cálculoSe hicieron muchas suposiciones
/*""" Optimize the computation
author: jthi
date: 2024-09-05
url: https://community.jmp.com/t5/Discussions/Optimize-the-computation/m-p/795219
keywords/tags: [semiconductor,wafer,distance,matrix,die]
Description: Calculate distance from center of wafer (coordinates) to corner of die
"""*/
Names Default To Here(1);
dt_temp = Open("$DOWNLOADS/XYCoord.jmp");
die_width = 1.160;
die_height = 0.810;
dt = dt_temp << Summary(
Group(:U1_x, :U1_y),
Freq("None"),
Weight("None"),
Link to original data table(0),
output table name("Coords")
);
dt << Delete Scripts(dt << Get Table Script Names);
// Use Update to join the distances back using U1_x and U1_y as linking ids
Close(dt_temp, no save); // Close as not needed for this demo
m_x = Column(dt, "U1_x") << get values;
m_y = Column(dt, "U1_y") << get values;
// Origo to 0, 0 and coordinates to "real" measures
// This most likely will require some adjustments but you know your data so you should be able to modify this as needed
xcoords = (m_x - Max(m_x) / 2) * die_width + die_width / 2;
ycoords = (m_y - Max(m_y) / 2) * die_height + die_height / 2;
// Distance from center to each of the corners of rectangle
// assumes that the "coordinate" is at the center of die
top_left = xcoords - die_width / 2 || ycoords + die_height / 2;
bottom_left = xcoords - die_width / 2 || ycoords - die_height / 2;
top_right = xcoords + die_width / 2 || ycoords + die_height / 2;
bottom_right = xcoords + die_width / 2 || ycoords - die_height / 2;
d_tl = Sqrt(Distance(top_left, [0 0]));
d_bl = Sqrt(Distance(bottom_left, [0 0]));
d_tr = Sqrt(Distance(top_right, [0 0]));
d_br = Sqrt(Distance(bottom_right, [0 0]));
// Assume that furthest part of die is the determining factor for distance
die_distance_to_center = Round(V Max((d_tl || d_bl || d_tr || d_br)`));
dt << New Column("D", Numeric, Ordinal, Values(die_distance_to_center));
nw = New Window("Demo",
H List Box(
dt << Data Filter(
Add Filter(columns(:D), Display(:D, N Items(15), Find(Set Text(""))))
),
gb = dt << Graph Builder(
Size(528, 463),
Show Control Panel(0),
Lock Scales(1),
Variables(X(:U1_x), Y(:U1_y)),
Elements(Points(X, Y, Legend(4))),
SendToReport(
Dispatch({}, "U1_x", ScaleBox,
{Format("Fixed Dec", 12, 0), Min(-2.87573722663528), Max(261.04),
Inc(50), Minor Ticks(1)}
),
Dispatch({}, "U1_y", ScaleBox,
{Format("Fixed Dec", 12, 0), Min(-3.300675), Max(380), Inc(100),
Minor Ticks(4)}
)
)
)
)
);
Write();


Re: Optimizar el cálculo@jthi
1. El centro de la oblea se determina calculando los rangos de las coordenadas X e Y (es decir, los valores máximos menos los mínimos). Las estimaciones iniciales para el centro se calculan de la siguiente manera:
- CentroXCoord = xcoordmin + xcoordrange / 4
- CentroYCoord = ycoordmin + ycoordrange / 4
Luego, el código ajusta iterativamente estas coordenadas dividiendo el rango de coordenadas por 1,8 en cada iteración hasta que se cumplan las condiciones de centrado de X e Y. El centro final se encuentra cuando las fórmulas de centrado para ambos ejes
2. El radio se calcula desde el centro de la oblea hasta la entrada del troquel "RadiusDieCenter" o el borde del troquel "RadiusDieEdge".
3. Solo el centro del molde debe estar dentro de los radios calculados. Los cálculos de radio se centran en la distancia desde el centro de la oblea hasta el centro de cada molde.