ChartDirector Support Forum Home   Search
Wafermap
Posted by William.Cook on Aug-02-2023 11:39
Couple of question:
1.   I sometimes have negative coordinates from my prober.  Do I need to convert them to zero base positive numbers.

2. can you change the "origin" of the coordintes,  what I mean is that 0,0 on the samples is at the lower left corner.   For instance, can you make the origin the upper left corner or any other corner?

Re: Wafermap
Posted by Peter Kwan on Aug-02-2023 22:35
Attachments:
Hi William,

You can use any x and y coordinates you like and put the (0, 0) anywhere you like.

In the discrete heat map (the wafer map is an usage of discrete heat map), the x-axis labels and y-axis labels are just names for human reading. You can use any labels you like. I have attached an example in which I can the x-axis labels to start from -4 on the right side, and goes to 15 on the left side. See attached image.

You can even use text for the axis labels, as in this example:

https://www.advsofteng.com/doc/cdnet.htm#discreteheatmap.htm

If you want to have the origin at the bottom right corner of the chart, you can set the x-axis labels to 19, 18, ..., 2, 1, 0 for the y-axis labels to 0, 1, 2, ..., 17, 18 19. You can put the y-axis on the right side by using XYChart.setYAxisOnRight.

The cell data are provided as an array of numbers. In the wafer map example, the array contains 400 elements for 20 x 20 cells. The first cell is at the bottom left corner, and it flows from left to right, bottom to top.

Best Regards
Peter Kwan

Re: Wafermap
Posted by William.Cook@vishay.com on Aug-03-2023 03:20
How would you handle a sparse map?    We do a sample test on the wafer, not all die are tested.   Can you provide the code for this doing this and for the Example of the previous example code, you showed wijth the lasat email.

Peter Kwan wrote:

Hi William,

You can use any x and y coordinates you like and put the (0, 0) anywhere you like.

In the discrete heat map (the wafer map is an usage of discrete heat map), the x-axis labels and y-axis labels are just names for human reading. You can use any labels you like. I have attached an example in which I can the x-axis labels to start from -4 on the right side, and goes to 15 on the left side. See attached image.

You can even use text for the axis labels, as in this example:

https://www.advsofteng.com/doc/cdnet.htm#discreteheatmap.htm

If you want to have the origin at the bottom right corner of the chart, you can set the x-axis labels to 19, 18, ..., 2, 1, 0 for the y-axis labels to 0, 1, 2, ..., 17, 18 19. You can put the y-axis on the right side by using XYChart.setYAxisOnRight.

The cell data are provided as an array of numbers. In the wafer map example, the array contains 400 elements for 20 x 20 cells. The first cell is at the bottom left corner, and it flows from left to right, bottom to top.

Best Regards
Peter Kwan

Re: Wafermap
Posted by Peter Kwan on Aug-03-2023 05:16
Hi William,

Sorry, I forgot to include the code in my last post. The code I used is based on C++. If you are using another programming langauge, please let me know.

I started from the "wafermap" sample code that comes with ChartDirector and modify the part about the x-axis labels:

void wafermap(CChartViewer *viewer, int /* chartIndex */)
{
// The diameter of the wafer
int diameter = 20;
double radius = diameter / 2.0;

// The random data array are for a square grid of 20 x 20 cells
RanSeries* r = new RanSeries(2);
DoubleArray zData = r->get2DSeries(diameter, diameter, 0, 100);

// We remove cells that are outside the wafer circle by setting them to NoValue
for(int i = 0; i < zData.len; ++i) {
double x = i % diameter + 0.5;
double y = (i - x) / diameter + 0.5;
if ((x - radius) * (x - radius) + (y - radius) * (y - radius) > radius * radius) {
((double*)(zData.data))[i] = Chart::NoValue;
}
}

// Create an XYChart object of size 520 x 480 pixels.
XYChart* c = new XYChart(520, 480);

// Add a title the chart with 15pt Arial Bold font
c->addTitle("Wafer Map Demonstration", "Arial Bold", 15);

// Set the plotarea at (50, 40) and of size 400 x 400 pixels. Set the backgound and border to
// transparent. Set both horizontal and vertical grid lines to light grey. (0xdddddd)
PlotArea* p = c->setPlotArea(50, 40, 400, 400, -1, -1, Chart::Transparent, 0xdddddd, 0xdddddd);

// Create a discrete heat map with 20 x 20 cells
DiscreteHeatMapLayer* layer = c->addDiscreteHeatMapLayer(zData, diameter);

// Set the x-axis scale. Use 8pt Arial Bold font. Set axis color to transparent, so only the
// labels visible. Set 0.5 offset to position the labels in between the grid lines.

// Generate the array of text strings from 15 to -4
std::vector<std::string> labelBuffers(diameter + 1);
std::vector<const char *> labels(diameter + 1);
for (int i = 0; i <= diameter; ++i)
{
char buffer[100];
snprintf(buffer, sizeof(buffer), (i - 5 >= 0) ? "%d" : "\%d", i - 5);
labelBuffers[i] = buffer;
labels[i] = labelBuffers[i].c_str();
}
std::reverse(labels.begin(), labels.end());

// Use the text strings as x-axis labels
c->xAxis()->setLabels(StringArray(labels.data(), labels.size()));

c->xAxis()->setLabelStyle("Arial Bold", 8);
c->xAxis()->setColors(Chart::Transparent, Chart::TextColor);
c->xAxis()->setLabelOffset(0.5);

// Set the y-axis scale. Use 8pt Arial Bold font. Set axis color to transparent, so only the
// labels visible. Set 0.5 offset to position the labels in between the grid lines.
c->yAxis()->setLinearScale(0, diameter, 1);
c->yAxis()->setLabelStyle("Arial Bold", 8);
c->yAxis()->setColors(Chart::Transparent, Chart::TextColor);
c->yAxis()->setLabelOffset(0.5);

// Position the color axis 20 pixels to the right of the plot area and of the same height as the
// plot area. Put the labels on the right side of the color axis. Use 8pt Arial Bold font for
// the labels.
ColorAxis* cAxis = layer->setColorAxis(p->getRightX() + 999, p->getTopY(), Chart::TopLeft,
p->getHeight(), Chart::Right);
cAxis->setLabelStyle("Arial Bold", 8);

// Output the chart
viewer->setChart(c);

//include tool tip for the chart
viewer->setImageMap(c->getHTMLImageMap("clickable", "", "title='<*cdml*>({xLabel}, {yLabel}) = {z|2}'"));

//free up resources
delete r;
}

Regarding the sparse map, if there is no data for a cell, you can simply set the cell to Chart::NoValue (in C++ syntax) or Chart.NoValue (in C#/Java/VB syntax). If most of the cells are Chart.NoValue, you can initialize the array to Chart.NoValue, and fill only the cells that have data.

The following is an example with Chart::NoValue cells. (Note the hole at the middle of the chart.)

https://www.advsofteng.com/doc/cdcpp.htm#heatmapcelllabels.htm

Best Regards
Peter Kwan