Using Image-Based Alignment


Introduction and Caveats

This document is intended to be a quick guide to using image-based alignment mark location on the EBPG, as an alternative to the standard edge-detection-based methods of finding marks. Using images to find marks has the advantage of allowing much more variation in mark shape (virtually anything will work to some extent, as long as the marks are all more or less identical), including standard Vistec marks that are too distorted to use with the standard algorithm.

There are some major tradeoffs to this method of alignment, however. The main one is accuracy; since this capability isn’t specifically built into the Vistec software yet, custom scripts are used to acquire, center, and correlate images. Alignment will only be as good as the centering of the reference-mark image; while the software will do its best to optimize this, expecting alignment tolerances much better than 1 μm when using this method is probably unrealistic. Throughput is also an issue, as acquiring an image of a mark can take quite a bit longer than just edge-scanning it, particularly if the search area is large.

User-friendliness is another major issue with the system as it is now. Shell scripts will do most of the heavy lifting, but familiarity with the Linux command line is a must. Additionally, the parameters that will result in successful alignment vary quite a bit with beam current, substrate, and mark type; some trial and error will almost always be necessary to make this work.


Overview

There are two steps to image-based alignment:

  1. Capturing a reference image

  1. Aligning to the reference image

Each of these steps has an associated shell script that needs to be run, and several parameters that can be changed.


Getting a Reference Image

Explanation

The image alignment works by capturing an image of an alignment mark, correlating it with a reference image, and moving the stage by the measured distance between the centers of the two images. As you’d probably guess, it’s critical to use a high-quality, well-centered reference image.

The getref script will use the current position of the stage as the basis for its reference image. It will also do its best to center the image by taking multiple low-quality images and running a center-of-gravity (COG) algorithm on each one before taking the final image.

The COG algorithm is somewhat picky about the shapes it works well on. The best inputs to the COG will be:

The COG will work to varying degrees on shapes that don’t meet these criteria, but results will be mixed. In cases where automatic centering really doesn’t seem to be working, a manual mode is provided.

Script Usage

The getref script has several command line options; running it with no arguments will give a brief explanation of those options, but they are covered here in more detail.

The simplest getref command line will look like this:

getref 100 20

Where the first number (100) is the width of the search area in microns, and the second number (20) is the width of the mark in microns. This command will snap a 100-μm-wide image centered on the current stage position, try to center it on a 20-μm-wide shape, and save the final high-quality image as reference.img in your /images directory.

There are lots of optional things you can add to the command line to make it behave differently, as summarized below:

-f
--filename
Save the image with a custom filename. Useful if you want to keep several different reference images around for different marks/samples. No extension is needed on the filename.
-q
--quality
Change the pixel-integration number (and, indirectly, the image quality) of the final reference image. The system will perform 2n integrations per pixel, where n is the argument here. Default is n=8. More integrations will give a better image, but can be very time-consuming.
-p
--passes
Change the number of passes in the COG-based centering operation. More passes can improve the centering, particularly when the mark is a shape the COG has problems with. Default is 3.
-m
--manual
Bypass the COG algorithm and center the mark interactively in CSEM (like the normal JOY routine). Can be useful if the COG absolutely can’t center your mark.
-n
--negative
Specify a negative-tone mark. The COG algorithm doesn’t work on negative marks, so we have to reverse the image in order to center it (if you’re doing manual centering, you can leave this off)

So a more complex command line could end up looking like this:

getref 100 20 -q 9 -p 7 -f GaAs?

Here we’ve set the integration to 512 (29), the number of COG passes to 7, and the output filename to GaAs.img The first two arguments always have to be the search area and the shape width, but everything else can be in any order you want.

Tips

Once the final image has been acquired, a gnuplot window displaying it (with crosshairs in the center to give you an idea of the final offset) should pop up. If for some reason this doesn’t happen, you can also inspect your final reference image with ImageJ?. To run it, type ij& at a prompt. Once in the program, go into the “file” menu and select “import” and “raw.” Put in the height/width of your image in pixels (this should have been printed when the getref routine finished) and check “Little-endian byte order”, then hit OK. Your image should now be displayed, allowing you to get a rough idea of how close to centered it is. If the image looks noisy or off-centered, try re-running getref with different parameters.

Try to make your search area big enough to include some space around your mark; correlations with other marks will fail if the mark you’re trying to align to falls partway outside the search area. A width of at least 2-3x your mark width is a good rule of thumb.

The COG algorithm does much better when the mark is already close to centered. Use CSEM to center the mark at a high magnification before running getref if the centering isn’t working. Additionally, the COG will usually fail completely if the mark isn’t completely captured somewhere in the search area, or if other structures besides the mark are present in the search area. Adjust your search area width appropriately.

Remember, this alignment technique is only as good as the reference image! Take some time and experiment with the settings in order to get the most centered, noise-free image possible.


Aligning with Images

Basics

Now that you have a reference image, you should be able to use it to align to identical marks on your sample. Set your job file up so that every image mark is referenced with the ‘joy’ (again, all lowercase) definition and export it. To use the default ‘reference’ as your reference image, just type image_on in the terminal window; to use some other reference image type image_on [filename] (no extension needed). If you're using a custom reference image filename provide it here; otherwise just leave out the filename argument. Once that’s done, you can execute the job per usual. The imgalign script will be called every time the system tries to align to a ‘joy’ mark now.

You don’t have to specify the mark size or search area size because the script will pull that information out of the text file that was generated when you took the reference image. If you keep getting mark-failure errors and seeing warnings like “poor correlation,” it’s possible that the image-capture of the alignment marks is too noisy and degrading correlation accuracy. You can increase the pixel-integration number in the alignment scans by editing the ALIGN_PIXEL_INTEGRATION variable (the default is n=6, or 64 integrations per pixel) according to the same rules as the -q parameter in getref. Likewise, you can vary the image-threshold value from its default of 0.7 to any value between 0 and 1 by editing the IMAGE_THRESHOLD variable. To edit an environment variable, use the export command:

export ALIGN_PIXEL_INTEGRATION=10

Keep in mind that every increase in the integration will increase the mark-scan time by a factor of two, which can seriously increase your write time since the system does a full scan for every single alignment mark in your layout. Likewise, messing with the threshold is generally not recommended unless you know what you’re doing; a low threshold can give false-positive mark locations and a high one can cancel out the alignment mark along with image noise. If you have to change it, try to stick to values between 0.6 and 0.8.

When the write is finished, use image_off (or simply close the terminal window) to revert the joy mark to its standard behavior. Note that the variable set with image_on won’t be visible outside the terminal window that you set it in, so you’ll want to execute your job file from the same window.

Tips

• Due to the system’s general flakiness, it is a very good idea to drive to each mark individually, center it in CSEM, and have the system try to locate it with the findmark joy command before you start the write. If it successfully finds the mark, use the stage position afterward as that mark’s position in the job command line. This will let you troubleshoot any location problems without having to restart your write multiple times.


How It Works

This setup exploits the fact that the ‘joy’ marker definition can be arbitrarily redefined. Normally, it acts as a “manual override” for alignment, allowing the user to align by eye using the SEM if the auto-alignment routines aren’t working. Changing the value of the PG_USER_JOYMARKER variable to point to an executable script, however, will cause the Vistec software to run that script whenever a ‘joy’ definition is encountered in a job file. The only purpose of image_on and image_off is to set and unset PG_USER_JOYMARKER, respectively. In this implementation, PG_USER_JOYMARKER is set to /home/pg/scripts/imgalign, with an optional reference-image argument. If you’d like to experiment with your own image-alignment algorithm, just save the script in your environment’s /scripts directory, make sure it’s executable, and set PG_USER_JOYMARKER to its full path before writing. Feel free to copy imgalign to your own directory to use as a template. Scripts can be written in any language that can be executed from a linux shell; there’s probably a much better implementation than this one if you’re good with Perl or Python or something.