User's Guide to Sigma0 1.0

Revised by Sharon Okonek from User's Guide to MacSigma0, written by Lynne Norikane and Anthony Freeman
June 24, 1996

Table of Contents

1. Overview
2. Sensor/Mission Description
3. Getting Started
4. The File Menu
5. The Edit Menu
6. The View Menu
7. The Image Menu
8. The Statistics Menu
9. The Windows Menu

Appendix A The Algorithms
Appendix B Transferring Data to the Macintosh
Appendix C Variable Format Header

Appendix D The "Old" Header

  1. Overview




Introduction



Welcome to Sigma0! Sigma0 is an interactive tool for the Macintosh or the PC which allows you to display and make computations from radar data collected by the following sensors:

In addition, headerless byte images can also be displayed and statistical computations made from them.

Sigma0 is based on the program MacSigma0 written by Lynne Norikane. Sigma0 is a modified version of MacSigma0 that uses the 'XVT Development Solution for C' from XVT Software, Inc. The XVT code that has been embedded into the program allows the same Sigma0 code to be compiled for the Macintosh or the PC. The modifications to MacSigma0 to create the Sigma0 code were made by Eric Turner, Sharon Okonek, and Matthias Ziegler under the guidance of Tony Freeman. Sigma0 is designed for use with the NASA/JPL education cd-roms SIR-CED01 and SIR-CED02.

What to Read



Sigma0 is designed so that its use is simple and intuitive. If you are an experienced Macintosh or PC user and already have an understanding of imaging radar, you will probably be able to go straight to the Tutorial in Chapter 3 (Getting Started). Chapter 2 gives a basic description of the sensors which Sigma0 supports data from. It is provided for those who wish to gain an understanding of how imaging radar works and what it measures. Chapters 4 - 8 give detailed descriptions of the File, Edit, Image, Statistics, and Windows menus. Appendix A contains all of the equations used in this program. If you have some experience with other Macintosh or PC applications, you may be able to learn how to use Sigma0 through experimentation alone!

Sigma0 Functionality



Sigma0 provides four basic functions: synthesis of images (if necessary), statistical analysis of selected areas, informative mouse tracking, and export of radar images as byte or TIFF files.

Supported Data Types

The types of images synthesized depend on the data type:

types of correlation coefficient images, namely HH-VV, HH-HV, and HV-VV.
For the complex and phase images, phase is displayed using color and magnitude
is displayed using intensity.

Statistics and Computations

The statistics and other information that can be calculated depend on the image type:

For all image types, the image name and appropriate information such as frequency band, polarization, sensor, and/or image identification are given. Coordinates of the selected area are also given. These coordinates must be interpreted differently, depending on the type of area selected. Three types of selections can be made: rectangular (one or more), linear, and polygonal.

The information shown in the statistics window can be printed or saved into a text file. The text file format is designed to allow easy merging of data from Sigma0 into a spreadsheet or plotting package.

Mouse Tracking

As the mouse is moved around on top of an image, the mouse's location and the associated pixel's value are shown in the lower left corner of the image window. The exact information shown depends on the data type:

Total power, HH, HV, VV:
sigma0 (dBs)
HHVV*, HHHV*, HVVV*, HHVV* phase:
phase (deg)
correlation coefficient:
correlation coefficient * 100


Annotation Options

A displayed image can be zoomed in and out within certain limitations. If the image has been zoomed in enough (i.e. the individual pixels are shown as fairly large squares), then appropriate values can be superimposed on top of the displayed pixels. The superimposed value depends on the image type:

Total power, HH, HV, VV, HHVV*, HHHV*, HVVV*:
sigma0 (dBs)
HHVV* phase:
phase (deg)
correlation coefficient:
correlation coefficient

In addition, titles or captions can be added either at the bottom of the image or on either side. These titles or captions are always shown within the window. In other words, their locations are not fixed.

Output Options

Grey scale computed images can be saved in a byte format (a headerless format which saves the image as a string of byte values). Byte format images are saved in their entirety, including those areas not currently shown in the image window. Only that part of the image currently displayed in the image window is saved.

Any image, including those requiring color, can be saved in TIFF format. Only that part of the image currently displayed in the image window is saved.


Requirements



There are actually two versions of Sigma0: "Sigma0 for the Macintosh" and "Sigma0 for the PC". Sigma0 for the Macintosh will run on any Macintosh with at least one graphics device which supports 4-bit video, but will not take advantage of an available 68881 compatible math coprocessor or the extended 68020 compatible instruction set. Sigma0 for the Macintosh also requires a minimum configuration of System 6.0, Finder 6.1, and 1 megabyte of memory. Since images are stored in memory, more memory is required if you will be examining large data sets. You may also wish to increase the amount of memory allocated to the program by doing the following BEFORE running the program: (1) click once on the Sigma0 icon, (2) select 'Get Info...' from the 'File' menu, and (3) change the Application Memory Size. You must set number of colors to 256 (MONITORS control panel).

Sigma0 for the PC requires at least a 486 CPU, Windows 3.1 or higher, and a VGA card that supports at least 256 color levels.

Both versions of the program are unable to determine whether color is available. If color is not available, any complex image or phase image will not be displayed correctly as they require color to display phase.

For future reference, both versions of the program will collectively be referred to as "Sigma0".


Supported image sizes



Sigma0 displays images that are at most 32767 x 32767 pixels. The maximum number of images which can be displayed depends on the amount of free memory on your system. Constraints on displayable image size is most often limited by the amount of free memory available to the application.

Input Data File Formats



Sigma0 is able to read up to four kinds of image data formats:

Compressed Stokes Matrix Format

The compressed Stokes matrix data format is composed of 10 bytes per pixel preceded by two ASCII headers, the variable format header and the "old" header. Both the variable format header and the "old" header are composed of 50-character fields where one character is saved per byte. In general, a compressed Stokes matrix data file looks like the following:





The following information is contained in the variable format header:

             Column numbers:
      Field  12345678901234567890123456789012345678901234567890

        1    RECORD LENGTH IN BYTES =                  NNNNNNNN
        2    NUMBER OF HEADER RECORDS =                NNNNNNNN
        3    NUMBER OF SAMPLES PER RECORD =            NNNNNNNN
        4    NUMBER OF LINES IN IMAGE =                NNNNNNNN
        5    NUMBER OF BYTES PER SAMPLE =              NNNNNNNN
        6    JPL AIRCRAFT SAR PROCESSOR VERSION       XXXX.XXXX
        7    DATA TYPE =                             CCCCCCCCCC
        8    RANGE PROJECTION =                          CCCCCC
        9    RANGE PIXEL SPACING (METERS) =           XXXX.XXXX
        10   AZIMUTH PIXEL SPACING (METERS) =         XXXX.XXXX
        11   BYTE OFFSET OF OLD HEADER =               NNNNNNNN
        12   BYTE OFFSET OF USER HEADER =              NNNNNNNN
        13   BYTE OFFSET OF FIRST DATA RECORD =        NNNNNNNN
        14*  UPPER LEFT CORNER X (0-1023) =            NNNNNNNN
        15*  UPPER LEFT CORNER Y (0-1023) =            NNNNNNNN
        16*  AVERAGING (1,2,4) =                       NNNNNNNN

where 'NNNNNNNN' represents a right-justified integer value, 'XXXX.XXXX' represents a right-justified real number, and 'CCCCCCCC' represents a character string. The number of bytes per sample (field 5) must be 10 and fields 11 and 13 must point to the "old" header (described below) and the beginning of the data respectively.

The contents of fields 14 through 16 vary depending on which AIRSAR processor was used and may not exist at all. It was hoped that they would be used to keep track of the relative location of the data set being examined with respect to the "original" data set. Sigma0 assumes that the "old" header was copied directly from the "original" data set. Thus if, for instance, the incidence angle of a particular pixel needs to be calculated, the program must be able to correctly interpret the geometric parameters which are stored in the "old" header which refer to the "original" data set. For more information about each of the fields in the variable format header, see Appendix C. For more information about fields 14 through 16, see Appendix B.

The "old" header is composed of approximately 160 50-character fields and contains information recorded during the acquisition of the data and information added during correlation and possibly calibration. In versions of the SAR correlator prior to 1990, this is the only header saved with each data set (it is saved in the 1025th line of the file). With the addition of the variable format header, this header became the "old" header.

The user header does not usually exist. If there is a user header on your data set, it will be ignored.

Byte Image Format

Sigma0 can read a byte image file containing only 8-bit pixel values (0-255 inclusive). The data is expected to be stored on a row-by-row basis (i.e. as the file is read sequentially, the image forms from left to right and top to bottom). Since the file does not contain any information about the dimensions of the image, the user is asked to supply the number of samples and lines in the image.

Printers



Not implemented in Sigma0 v1.0.

Differences Between MacSigma0 and Sigma0



The major differences are outlined below:

[1] Versions are now available for the Macintosh and the PC.

[2] Multiple images can be displayed.

[3] Synthesizes two new kinds of correlation coefficient images, HH-HV and HV-VV.

[4] Grey scale and color images can now be saved in TIFF or BMP format.

[5] AIRSAR old header can now be viewed (along with the variable header).

[6] When scrolling around the image with the mouse, db, phase, magnitude values are now displayed depending on the image type.

[7] Areas selected for statistical analysis can be drawn on all open windows using the 'Draw Selected On All' feature.

[12] There is a new 'Set Zoom Factor' feature.

[13] Does not support Magellan MIDR framelet, ERS-1, or JERS-1 data formats.

[14] Does not have the analyze reflector capability.

[15] Cannot print an image directly to your printer from Sigma0.

[16] Only one area allowed at a time for statistics.


Known Bugs



Bugs that exist in Sigma0 v1.0 are:

[1] Trying to open a very large data file make cause a heap memory error.

[2] PC version: Cannot open PICT files.

[3] PC version: When saving statistics to an output file, two funny characters appear at the top of output file.

[4] May get an invalid window handle error when quitting Sigma0. This will be fixed in the next version which will use the latest version of the XVT software.

[5] PC version: About this Data option does not display old header.

[6] PC version: Exitting Sigma0 with the 'About this Data' window open causes a stack fault. To avoid this error, make sure this window is closed before exitting.

[7] PC version: When copying an area in an image and pasting the area into another application, may see only a few color levels rather than the whole 256 levels.

[8] Images saved in BMP format have garbage data appended to them.


References



For information about polarimetry and the conventions used by this program, see:

Zebker, H. and vanZyl, J., "Imaging Radar Polarimetry: A Review", Proceedings of the IEEE, Vol. 79, No. 11, November 1991.

Zebker, H., vanZyl, J., and Held D., "Imaging Radar Polarimetry From Wave Synthesis", Journal of Geophysical Research, Vol. 92, No. B1, pp 683-701, January 10, 1987.


Other sources of information on polarimetry are the following:

Born. M. and E. Wolf, Principles of Optics, Sixth Edition, pp 24-32, Pargamon Press, New York, 1980.

Giuli, D., Polarization Diversity in Radars, Proceedings of the IEEE, Vol. 74, No. 2, pp 245-269, 1986.

Huynen, J. R., Phenomenological Theory of Radar Targets, Ph. D. Dissertation, Drukkerij Bronder-Offset, N. V. Rotterdam, 1970.

Van de Hulst, H. C., Light Scattering by Small Particles, pp 28-59, Dover, New York, 1981.
VanZyl, J. et. al., Imaging Radar Polarization Signatures: Theory and Observation, Radio Science, Vol. 22, No. 4, pp 529-543, July/August 1987.

Zebker, H., et. al., "Calibrated Imaging Radar Polarimetry: Technique, Examples, and Applications, IEEE Transactions on Geoscience and Remote Sensing, Vol. 29, No. 6, November 1991.


Web Site:
For more information on imaging radar, NASA/JPL software and radar data products, and more, please visit the NASA/JPL Imaging Radar Home Page on the World Wide Web at http://southport.jpl.nasa.gov.

  1. Sensor/Mission Description




JPL AIRSAR (A. Freeman)



The JPL AIRSAR systems are side-looking imaging radars which utilize the Synthetic Aperture principle to obtain high resolution images which represent the radar backscatter of the imaged surface. The image coordinates are usually slant or ground range and azimuth. Slant range is a measure of the radial distance of the image object from the radar. Ground range is a measure of the distance of the object from a point directly below the aircraft. Near range in the images is closest to the aircraft and far range is furthest away. The azimuth dimension in the images is parallel to the line described by the track of the aircraft. (See the figure at the end of this section). The spatial resolution of the JPL AIRSAR images, which determines how far apart two objects have to be in order to separate them in the image, is on the order of 12 x 12 meters. Note that this is not the same as the range or azimuth pixel spacing which is contained in the variable format header of the AIRSAR data.

The information contained in each pixel of the AIRSAR data represents the radar backscatter for all possible combinations of horizontal and vertical transmit and receive polarizations (i.e. HH, HV, VH, and VV). The data is in compressed Stokes matrix format, which has 10 bytes per pixel. From this data format it is possible to synthesize a number of different radar backscatter measurements. Sigma0 allows the synthesis of images and analysis of data for some of the more important radar backscatter measurements for AIRSAR data. Each pixel contains information about the radar backscatter for a single frequency only. Other image files may be available which contain information about the radar backscatter at different frequencies. The radar backscatter measurement is a strong function of incidence angle, which is defined as:

qi = cos-1(h/(R0+iDR))

where h is the altitude of the aircraft (typically about 8 km), R0 is near range in the image (typically 8-10 km), DR is the size of the (slant) range pixels in meters and i is the line number of the object in the image. The incidence angle is defined with respect to the normal to the Earth's surface. The above expression is strictly valid for a flat Earth only. Radar backscatter usually has a tendency to decrease as the incidence angle increases. This effect can often be seen in AIRSAR images, where the incidence angle is typically in the range of 0 to 70 degrees. The smaller incidence angles correspond to near range in the AIRSAR data, while the larger incidence angles correspond to far range.

Much of the data produced by the AIRSAR is now calibrated, so that the radar backscatter measurements are in normalized radar cross section format (m2/m2) or s0. s0 is the radar cross section (measured in m2) normalized by the area of the measurement, which in this case is the pixel area in square meters. Sigma0 is designed to operate only on calibrated AIRSAR data products. Results obtained using Sigma0 on uncalibrated AIRSAR data should be treated with caution.

The direct measurements of radar backscatter which are made by the AIRSAR systems are the elements of the scattering matrix,



which represent the backscatter for each pixel in response to the 4 different combinations of H and V transmit and receive polarizations. Shv is the scattering matrix term for H transmit, V receive, for example. The scattering matrix measurements are complex numbers, with amplitude and phase.

The Shv and Svh measurements are equal by the principle of backscatter reciprocity. In AIRSAR data, only the Shv term is retained. The AIRSAR data is issued in compressed Stokes matrix format. An intermediate step in forming the Stokes matrix for each pixel is to form the cross-products:

(1) Shh Shh* shh0
(2) Shv Shv* shv0
(3) Svv Svv* svv0
(4) Shh Svv*
(5) Shh Shv*
(6) Shv Svv*

These cross-products can be recovered from the Stokes matrix data format, which can be considered as a type of coding. Sigma0 allows each of these to be displayed. The first three are s0 measurements. The last three are complex numbers, with amplitude expressed in s0 and a phase term which can be expressed in degrees. The phase is between -180 and 180 degrees. In displaying the ShhSvv* term using Sigma0, for example, the amplitude is displayed as a grey scale, the phase as a color representation.

Experience with AIRSAR data has shown that the first four cross-products contain the most information about the imaged surface. Statistics on these parameters are automatically generated in Sigma0 in the statistics window when the 'Mean and std dev' menu item is selected. This is in addition to the statistics and histogram generated for the currently displayed parameter.

Sigma0 is designed to simplify the procedure of extracting radar backscatter information from AIRSAR data, so that the user of AIRSAR data can quickly generate results. The reader interested in more background information on radar polarimetry is referred to the papers listed at the end of Chapter 1.

The following diagram may clarify some of the geometric terms mentioned previously:






  1. Getting Started



Copying the application



You should have received with this manual and one 1.3MB floppy disk. The floppy disk contains the executable Sigma0 program (Macintosh or PC version), and AIRSAR data set of the San Francisco Bay area, a location map which contains a key to the AIRSAR radar image of San Francisco, and a README file with additional information.

Starting the application



To run Sigma0, double-click on the application's icon:



Tutorial



This tutorial is designed to introduce the first-time user to the features of Sigma0. It assumes that you are familiar with operating a Macintosh or a PC. If you are not, consult the user's manual before beginning this tutorial.

This tutorial uses JPL AIRSAR data as the example data set. Hints for using other types of data are included in square brackets. The graphics used in this tutorial are taken from a Macintosh system. The graphics on the PC will look slightly different, but the content and functionality will be the same.

Displaying an image

+ Select the 'Open compressed Stokes...' menu item in the 'File' menu and select the data file from Disk 2 called SANFRANL.STK.




The following dialog box should appear:




+ Select an image type to compute from the Stokes matrix data by clicking on the associated radio button. (Total power images are computed the fastest, so you might want to try this first).

If you selected any image type other than HHVV* phase and correlation coefficient, the following dialog box is presented:





A histogram of the image is displayed. The grey bar represents the range of the histogram that will be converted from 0 on the left to 255 on the right. Values falling to the right of the grey bar are all converted to 255 and values falling to the left are all converted to 0.

+ Near the right edge of the grey bar, click and hold the mouse button. Drag the mouse to about the middle of the grey bar and let go of the button. The window should now look like this:





The same can be done on the left inside edge of the grey bar.

+ Now select the 'OK' button.

An image window will appear and the image will be displayed as it is being calculated. You can cancel the operation by pressing Command-'.'. When the calculations are finished, you will see something like the following:






Exploring the data

+ Move the mouse around on top of the image. The values in the upper left corner of the image change as the mouse is moved. The values shown are: sample number, line number, byte pixel value (dn), and sigma0 in dBs. (If the calculated image is complex or phase only, then the third value is phase quantized to 2 degrees. If the calculated image is a correlation coefficient image, then the third value is the correlation coefficient times 100). You can toggle the coordinate window on or off by selecting 'Coordinates' under the View menu.

The sample number and line number start with (0,0) in the upper left-hand corner and increase to the right and towards the bottom.

+ Select the 'About this data...' menu item from the 'File' menu to see the contents of the variable format header and the old header:





+ Use the scroll bar on the right to scroll down to see the contents of the old header. Select 'Close' from under the File menu to close the window (or click on the little square in the upper left corner of the 'Data Display' window).

Manipulating what you see

+ Select the 'Zoom in' menu item from the 'Image' menu. Note that the pixels are now twice as large as before. Select either the 'Normal' or 'Zoom out' menu items to return the pixels to their normal size.

Each application of 'Zoom in' or 'Zoom out' increases or decreases the pixel size respectively. Once the limits of zooming have been reached, the computer issues a system beep.

+ Select the 'Zoom in' item several times until the 'Display sigma_0s' menu item becomes hilighted. Alternately you can also select the 'Set Zoom Factor' item and enter a value of 10.0 (the maximum zoom factor allowed). After setting the zoom factor select 'Zoom In'. You can use the image window's scroll bars to roam around the image. Now select the 'Display Sigma_0s' menu item. The sigma0 values in dBs will be drawn on top of each pixel in the window:





(If the image type were HHVV* phase or correlation coefficient, then the value displayed on top of the pixels would be the phase quantized to 2 degrees or the correlation coefficient times 100).

+ Select 'Normal Size' from the Image menu to get back to the normal size image of San Francisco. Now select 'Add Captions...' from the 'Image' window. You should see the following:





+ Enter a new caption if you want and select 'displayed' and 'OK'.

The image window will now look like:





Saving what we see

+ To save what is currently being displayed in the image window as a TIFF file, select the 'Save as TIFF' menu item in the 'File menu.

Analyzing the data

+ Return the data to its original state by selecting the 'Normal' menu item in the 'Image' menu.

Before we can analyze the data, we must select an area of the image to analyze. There are three types of selection areas: rectangles, lines, and polygons. The easiest two to use are rectangles and lines.

+ Select either 'Select rectangles..' or 'Select lines' from the 'Statistics' menu. Now try clicking and dragging in the image window. If you are selecting rectangles, then try selecting multiple rectangles by holding down the SHIFT key while selecting additional rectangles. If you are selecting lines, then try selecting the 'Line options...' menu item in the 'Statistics' menu to change the line width.

Clicking once in the image window deselects any selection previously made.

+ Now try selecting polygonal areas. Select the 'Select polygons...' menu item from the 'Statistics' menu. Click once where you want the first vertex. Click again where you want the next vertex. Continue in this manner until you are ready to close the polygon. To connect the previous vertex to the first, double-click. If there are fewer than 3 vertices, then the polygon is invalid and is deselected.

+ Once you have an area selected, select the 'Mean and std dev' menu item in the 'Statistics' menu. The program will compute the statistics for the selected area and will display something like the following (this may take a long time if you have a large selected area):





(The actual statistics displayed vary with the data type and image type).

+ You can save the statistics in a text file by selecting the 'Save as text' button in the window.

+ Time permitting, try the following exercise. Select areas representing different types of terrain (e.g. ocean, urban areas, forested area). For each area, calculate statistics and save them into a text file. From each text file, select the line containing each parameter separated by tabs. Import this line (e.g. using 'Copy' and 'Paste') to a graphing or spreadsheet package, thereby combining data from each area into one document or file. Try plotting HH, HV, and VV as a function of the area. The following shows some suggested areas for analysis:





An additional exercise might be to gather statistics from the ocean at different incidence angles and plot HH, HV, and VV as a function of incidence angle.

To see how the 'Draw Selected On All' feature works, first make sure you have drawn a region of interest on the current image window. Now bring up another polarization of San Francisco (under the File menu, select 'Open Comprsd Stokes...' to open the San Francisco data set and select the HV polarization). A new image window appears. Under the View menu, select 'Draw Selected On All'. A copy of the boundary lines that define the region of interest in the first image window is drawn in the second image window. Now you can compare statistics on identical regions in the two windows.

Getting the most out of Sigma0



The following are some hints to help you get the most out of Sigma0.

[1] Use the 'Save as TIFF' menu item to generate radar image data in a format that can be imported into many other applications.

[2] Use the 'Save as byte' menu item to generate radar image data in a format compatible with many other image processing applications.

[3] The data which appears in the 'Statistics' window can be saved to a text file. The line in the text file containing all of the calculated parameters separated by tabs can be imported into graphing and spreadsheet applications. (To calculate statistics, select an area and use the 'Mean and std dev' menu item).

[4] You must zoom in several times before the 'Display sigma0' option becomes available. (The displayed pixel size must be large enough to contain the overlayed text!)

[5] Open several windows representing different polarizations and/or frequencies at the same time. Use the mouse to select an area in one of the windows. Under the View menu, select the 'Draw Selected On All' item to draw identical regions in all the windows. Compare the statistics for each image.


Low memory conditions



When Sigma0 starts to run out of memory, it will prompt you with a message such as:





You must exit the program and reset the amount of memory allocated to the program. To do this on the Macintosh, click once on the Sigma0 application icon and select 'Get Info' from the 'File' menu. Examine and increase the amount of memory shown in the 'Application Memory Size (K)' box in the lower right-hand corner of the window. If doing this does not alleviate the problem, then you will need to reduce the size of the data that you are examining. Please see Appendix B for more information about how you may do this.

On the PC, Windows will automatically take the memory it needs. If Sigma0 starts running very slowly, you'll know that you are pushing the memory limitations of the computer.


  1. The File Menu





About the File Menu



Selecting the 'Open Cmprsd Stokes...' item will bring up a menu in which you select which compressed stokes data file you want to read into the program. Selecting the 'Open As...' item and dragging the mouse to the right will activate a pull down menu that contains 'Open Cmprsd Stokes', 'Open Byte Image', 'Open Mac PICT', and 'Open Win BMP'. Selecting 'Close' will close the current window. Selecting 'Save' will save the current image as a byte image. Selecting 'Save As' will activate a pull-down menu in which you can select 'Save As Byte', 'Save As MacPICT', 'Save As BMP', and 'Save As TIFF'. Selecting 'Quit' will quit Sigma0.
'Set Halftone' and 'Print' are not activated in Sigma0 version 1.0.


Open compressed Stokes...



To open a compressed Stokes matrix data set, select the 'Open compressed Stokes...' item from the 'File' menu. The following dialog box will appear asking you to select what data set to examine:




Note that the dialog box shown above allows you to select from many different file types rather than just one file type. You are expected to know which files actually contain legitimate compressed Stokes matrix data. Sigma0 lets you choose from many different file types because it does not know what program you may have used to generate or transfer the data files and consequently what types of files contain legitimate data.

After you have selected the file to open, click on 'Open' or 'Cancel'. You are then asked to select the type of image to synthesize:





If the image type selected is HHVV*, HHHV*, HVVV*, or HHVV* phase, then the image generated will be in color. Phase is displayed using color and magnitude, if applicable, is displayed using intensity. All other image types generate grey scale images. For more information about how the images are calculated and displayed, see Appendix A.

After you have selected an image type, a representative histogram of the output image is displayed:





For smaller images, the histogram may appear quantized because of the smaller number of pixels selected to generate the histogram.

The grey bar underneath the histogram represents the region of values which are mapped from 0 to 255. In the initial configuration, the minimum histogram value (on the far left) is mapped to 0 and the maximum histogram value (on the far right) is mapped to 255. To change the configuration, you must select a point INSIDE the grey bar near the edge you want to change. A small vertical line will follow the cursor until you release the mouse button. Values which fall above and below the right and left edges of the grey bar are mapped to 255 and 0 respectively. After you have altered the grey bar to your satisfaction, either select the 'OK' button to continue or 'Cancel'.

If 'OK' was selected, then the program computes the image. As it is computing the image, the portion of the image computed so far is displayed in the image window. For more information about how images are computed, see Appendix A.

Once the image has been computed, it should appear something like the following:





Note that as you move the mouse over the image, the x, y, and an additional parameter are displayed in the upper left corner of the window. Note that the (0,0) origin is located in the upper left hand corner of the image. The additional parameter displayed depends on the image type:

image type parameter display

total power total power (dBs)
HH HH (dBs)
HV HV (dBs)
VV VV (dBs)
RL RL (dBs)
RR RR (dBs)
HHVV* HHVV* phase (deg)
HHHV* HHHV* phase (deg)
HVVV* HVVV* phase (deg)
HHVV* phase HHVV* phase (deg)
correlation coefficient correlation coefficient * 100

Note that if phase is being displayed, it is quantized to 2 degrees. The correlation coefficient *100 and parameters in dBs are all quantized to integer units.

Also note that the window title is composed of the original file name, the frequency of the data (L, C, or P band), and the image type.

To open another compressed image or to synthesize another polarization from the same compressed image, repeat this procedure.

Open Byte Image..



To open a byte image, select File menukOpen AskOpen Byte Image. A byte image file does not have a header, therefore you are asked to supply the image dimensions in the following dialog box:





As you enter the number of samples, the number of lines is updated such that the product of samples and lines is equal to the file size. The dimensions must be no greater than 32767 x 32767 pixels. Select 'OK' or 'Cancel'.

After you have selected the image size, the image will be displayed in the image window. In the lower left-hand corner of the window, the x, y, and pixel value are displayed as you move the cursor over the image.

Open Mac PICT...



To open a PICT-formatted image, select File menukOpen AskOpen Mac PICT. A window will pop up in which you choose the PICT file. The image is then immediately displayed. This option only works under the Macintosh version of Sigma0.

Open Win BMP...



To open a BMP-formatted image, select File menukOpen AskOpen Win BMP. A window will pop up in which you choose the BMP file. The image is then immediately displayed.

After the image is opened



Once an image is displayed in a window, you can move the window around, change the size of the window, and scroll through the image.

To move the window around, click on the window's title bar and drag the window to its new position. If you want to change the size of the image window, click on the window's grow box in the lower right-hand corner and drag the mouse until the window is the size you want. If the window's scroll bars are active, you can use them to scroll through the image. Click in the zoom box in the upper right-hand corner of the image window to make the window as large as possible, but not larger than the size of the screen containing the menu bar. Click the zoom box again to make the window return to its original size.

About this data...



If a Stokes image is currently being displayed, then you can view the contents of the variable format header and the old format header by selecting this menu item. The variable format header is shown as follows:





Close



The 'Close' item in the 'File' menu is hilighted whenever an image window is the currently active window. Selecting this item closes that window.

Save as Byte, Save as BMP, Save as TIFF...



The Save As...kSave as Byte..., Save As...kSave as BMP..., and Save As...kSave as TIFF... items are available when the active window is the image window. 'Save as byte...' is available when the active window is a grey scale image such as a byte image or an HH image. It is not active when the window contains a color image (like a complex or phase image). After selecting 'Save', the entire image is written as a headerless stream of bytes into the file. The BMP format is a typical image format for the PC. TIFF is a tag-based file format for storing and interchanging raster images. BMP and TIFF formats are available for both color and grey scale images. Sigma0 asks you to select the name of the file to save your image in:





Enter the name of the output file you will save your image in. After selecting 'Save', the portion of the image currently visible in the image window is written into the file.


Quit



Selecting 'Quit' from the 'File' menu closes all windows and terminates the application.
  1. The Edit Menu





Copy



Only the 'Copy' item is supported in the 'Edit' menu. To use 'Copy', select a single rectangular area within the image window. Select 'Copy'. The portion of the image contained within the selected area, including overlayed sigma0 values and captions, will be stored in the scrap heap and can then be pasted into other applications' documents.

If instead of selecting a rectangular region you select a polygon or line region, the contents of the entire window will be stored in the scrap heap.

  1. The View Menu





View Coordinates



Selecting 'View Coordinates' will toggle the visibility of the information window that appears in the upper left corner af an image window. This information window contains the x and y position of the mouse, and the byte pixel value of the at the mouse location. If the image is a total power, HH, HV, VV, RL or RR image, the dB value will also be displayed in the information window. If the image is a complex image, the magnitude of the pixel location will be displayed. If the image is a phase only image, the phase value will be displayed in the information window. If the image is a correlation coefficient image, the correlation coefficient is displayed for the mouse location.


The example below shows what the image window looks like with 'View Coordinates' selected:











The example below shows what the image window looks like with 'View Coordinates' de-selected:










Draw Selected On All



Selecting 'Draw Selected On All' causes a currently selected region (rectangle, line, or polygon) to be redrawn on all the image windows in the current session. In the following example, three images were synthesized - TP, HH, and VV. A rectangle was drawn in the TP image window. 'Draw Selected On All' was selected and boundary boxes of the same size and location as the one in the TP window were drawn in the HH and VV windows:


TP, HH and VV images were synthesized. A rectangular region was then drawn on the TP image window:




Next, 'Draw Selected On All' was selected. The same rectangular region can now be seen on the HH and VV image windows:









  1. The Image Menu





Display Sigma_0's



The 'Display sigma_0' menu item is only available when an image window is open and the image has been zoomed in enough. If the image is a byte image then the menu item is changed to 'Display pixel values'. If the image is an HHVV* phase image, then it is changed to 'Display phase'. If the image is a correlation coefficient image, then it is changed to 'Display corr coefs'.

After selecting this menu item, the appropriate values are displayed on top of each pixel in the image. The following is an example:





The values displayed are the following:

image type parameter displayed

JPL AIRSAR:
total power total power (dBs)
HH HH (dBs)
HV HV (dBs)
VV VV (dBs)
RL RL (dBs)
RR RR (dBs)
HHVV* |HHVV*| (dBs)
HHHV* |HHHV*| (dBs)
HVVV* |HVVV*| (dBs)
HHVV* phase HHVV* phase (degrees)
correlation coefficient correlation coefficient * 100

byte image: pixel value

Correlation coefficients * 100 and dBs are rounded to integer values. Phase is rounded to the nearest even integral number of degrees. For more information about the calculations, see Appendix A.

Add Captions...



If an image window is open, you can select 'Add Captions...' to add a title to your image. The following dialog box appears:





Using the small pull down window in the upper left corner of the menu, you can select between 'Enter caption' or 'Entering side caption'. 'Enter caption' will cause your caption to be placed in the center of the current image. 'Enter side caption' will add a caption to either the left or right side of the current image. Two lines of text can be entered as a title for the image. You can also choose the location of the caption (left, center, or right) and the color (black on white background or white on black background). To cause the caption to be visible on the image, check the box labeled 'displayed'. The following is an example of an image with a caption:





Note that the caption is always located within the currently displayed portion of the image. To remove the caption, select the 'Add Captions...' menu item and de-select the 'displayed' box.

Normal size



The 'Normal size' menu item is used to command the program to display the image at a 1:1 ratio, i.e. 1 display pixel per 1 image pixel.

Zoom in



To zoom in, select the 'Zoom in' menu item. Note that once the image has been zoomed in sufficiently, the 'Display sigma_0' menu item becomes available.

Zoom out



To zoom out, select the 'Zoom out' menu item. If the resulting image would be too small to correctly display the scroll bars and coordinates window, then the computer issues a beep and the image is not zoomed out.

  1. The Statistics Menu





Select rectangles



There are three types of areas that can be selected for statistical analysis: rectangles, lines, and polygons. To select a rectangular area, choose 'Select rectangles' from the 'Statistics' menu.

To actually select an area in the image, click and drag. A rectangular box should move with the cursor until you release the mouse. The selected rectangle will be visible in the image window. To deselect the area, click once anywhere in the image portion of the window.

Select lines



To select linear areas (i.e. lines with non-zero width), select 'Select lines' from the 'Statistics' menu. To actually select the linear area, click and drag. A line should move with the cursor until you release the mouse. Once the mouse is released, an outline of the line with the selected width (see 'Line options...' below) will appear. To deselect the linear area, click once anywhere in the image portion of the window.

Select polygons



To select polygonal areas, select 'Select polygons' from the 'Statistics' menu. To draw the polygon, click on the starting vertex. A line should now follow the mouse around with one end connected to the vertex last selected. To add additional sides to the polygon, click on consequtive vertices. When you wish to close the polygon, double click anywhere in the image window. The last vertex selected and the first vertex will be automatically connected.

Note that polygonal areas differ slightly from rectangles and lines when determining which pixels are included inside the selected region. For example, if the user were to select a rectangular area with 'Select rectangles' and corner points (10,10) and (15, 12), the selected region would be as follows:





However, if the user were to select the same area with 'Select polygons', the selected region would be as follows:





Vertices in a polygon are used to defined an outline around the pixels which are to be selected. Thus vertices themselves are sometimes not included as one of the selected pixels.

Mean and std dev



Once you have selected an area, you can select the 'Mean and std dev' menu item. The program will calculate statistics of the selected area. The statistics calculated are at least the following if the image is an AIRSAR image:

parameter statistics calculated

HH mean (dBs), relative standard deviation
HV mean (dBs), relative standard deviation
VV mean (dBs), relative standard deviation
HHVV* phase mean (deg), standard deviation (deg)
HH-VV correlation coefficient mean, relative standard deviation

The relative standard deviation is defined as (m + s) / m where m is the mean and s is the standard deviation.

If the selected image type is different from all of those listed above, then the following additional statistics are calculated:

image type statistics calculated

total power mean (dBs), relative standard deviation
RL mean (dBs), relative standard deviation
RR mean (dBs), relative standard deviation
HHVV* |HHVV*| mean (dBs), relative standard deviation
HHHV* |HHHV*| mean (dBs), relative standard deviation
HHHV* phase (deg), standard deviation (deg)
HVVV* |HVVV*| mean (dBs), relative standard deviation
HVVV* phase (deg), standard deviation (deg)

For JPL AIRSAR data, the statistics window typically looks something like the following:





The image name is the name of the data file being examined. If appropriate, the frequency is displayed following the image name. Then the incidence angle is displayed. If the selected area was a rectangle or line, then this incidence angle is that of the center pixel. If the selected area was a polygon, then it is the mean incidence angle. If more than one area was selected or if the incidence angle could not be computed because of some strange image geometry (which sometimes occurs when the receiver was turned on too early), then the incidence angle is indicated as "**". The incidence angle, if displayed, is followed by the number of selected pixels. The heading "Rel stddev" is appropriate for all parameters except phase parameters for which the standard deviation is calculated.

Note that the histogram shown has been normalized such that the integrated area is equal to 1. The text in the lower left hand corner of the window indicate what histogram is being displayed and the units of the horizontal axis.

If the image displayed is a byte image, then the mean pixel value and the standard deviation are calculated:





The mean and standard deviation are in units of pixel values (0-255).

After the statistics have been being displayed, you can press the 'Save as text' button in the statistics window to save the statistics into a text file. After you select the button, you are asked to choose the output file name. If the file you select already exists, then you will be asked to cancel the operation or replace the file. The resulting text file can be opened and read by any word processing program. The following is an excerpt from a sample statistics text file for JPL AIRSAR data:

Image name:  SANFRANL.STK_TP (L-BAND)
(0) Center incidence angle:  39.7 degrees
Number of pixels: 1974
Selected rect:  (73,87) (119,128)
(1) TP mean: -15.80 dB
(2) TP relative standard deviation: 2.53
(3) HH mean:  -13.05 dB
(4) HH relative standard deviation:  2.70
(5) HV mean:  -22.13 dB
(6) HV relative standard deviation: 2.46
(7) VV mean:  -13.62 dB
(8) VV relative standard deviation:  2.61
(9) HHVV* phase mean:  -172.60 degrees
(10) HHVV* phase standard deviation:  115.96 degrees
(11) Correlation coefficient mean:  0.23
(12) Correlation coefficient relative standard deviation:  2.86
(0)	(1)	(2)	(3)	(4)	(5)	(6)	(7)	(8)	(9)	(10)	(11)... 39.7	-15.80	2.53	-13.05	2.70	-22.13	2.46	-13.62... 
 
Histogram type:  TP
Units:  dBs
-100.00	0.00000
-99.00	0.00000
-98.00	0.00000
...
-29.00	0.00152
-28.00	0.00608
-27.00	0.04863
-26.00	0.08511
-25.00	0.06383
-24.00	0.03698
-23.00	0.03445
-22.00	0.02989
-21.00	0.03597
-20.00	0.05978
-19.00	0.05471
-18.00	0.05370
-17.00	0.06383
-16.00	0.06738
-15.00	0.08055
-14.00	0.07700
-13.00	0.06130
-12.00	0.05471
-11.00	0.03141
-10.00	0.02077
...
95.00	0.00000
96.00	0.00000
97.00	0.00000
98.00	0.00000
99.00	0.00000

Note that each statistic is labeled with a number, e.g. (4). For JPL AIRSAR data, the labels are assigned according to the following chart:

(0) incidence angle
(1) TP mean
(2) TP relative standard deviation
(3) HH mean
(4) HH relative standard deviation
(5) HV mean
(6) HV relative standard deviation
(7) VV mean
(8) VV relative standard deviation
(9) HHVV* phase mean
(10) HHVV* phase standard deviation
(11) correlation coefficient mean
(12) correlation coefficient relative standard deviation
(13) |HHVV*| mean
(14) |HHVV*| relative standard deviation
(15) |HHHV*| mean
(16) |HHHV*| relative standard deviation
(17) HHHV* phase mean
(18) HHHV* phase standard deviation
(19) |HVVV*| mean
(20) |HVVV*| relative standard deviation
(21) HVVV* phase mean
(22) HVVV* phase standard deviation
(23) RL mean
(24) RL relative standard deviation
(25) RR mean
(26) RR relative standard deviation

Note also that before the histogram portion of the file, the statistics are written a second time, but are written out in one row with each statistic separated by a tab. The label above each statistic allows the user to determine which statistic it is by cross referencing the labels with those shown in the first part of the file. If a statistic was not calculated, it is left blank. The most commonly used parameters are contained in items 0 through 12.

By selecting the previously described row from multiple statistics text files and entering them into a spreadsheet or plotting program, you can do additional analysis on your data such as examining the effects of incidence angle for a particular vegetation type.

Note also that the histogram is stored as two text columns separated by a tab. The first value corresponds to sigma0 (in dBs), phase (in deg), correlation coefficient, or pixel value and the second value is the associated histogram value. The histogram can be selected and entered into a spreadsheet or plotting program for additional analysis.

The following is an excerpt from a statistics output file for a byte image:

Image name:  image256x274.byte
Number of pixels:  1570
Polygon's frame:  (109,58) (159,104)
(0) Mean:  183.43
(1) Standard deviation:  28.75
(0)	(1)
183.43	28.75
Histogram type:  BYTE
Units:  pixel  values
0.00	0.00000
1.00	0.00000
2.00	0.00000
3.00	0.00000
...
124.00	0.00127
125.00	0.00064
126.00	0.00318
127.00	0.00191
128.00	0.00064
129.00	0.00127
130.00	0.00255
131.00	0.00127
132.00	0.00191
133.00	0.00318
134.00	0.00446
135.00	0.00191
136.00	0.00064
137.00	0.00255
138.00	0.00510
139.00	0.00382
...
250.00	0.00000
251.00	0.00000
252.00	0.00000
253.00	0.00000
254.00	0.00000
255.00	0.00000


Analyze Reflector..



The 'Analyze Reflector' option is not active in Sigma0 version 1.0.

Line options...



To modify the width of any consequent linear areas to be selected, first select 'Select Line' under the Statistics menu. This will activate the option 'Line options...' from the 'Statistics' menu. The following dialog box appears when you select 'Line Options...':





Enter the width of the line. Make sure it is an odd integer. Select 'OK' or 'Cancel'.

The line width is not actually implemented rigorously, but implemented as shown below:





For lines which are closer to horizontal than to vertical, the line width is applied vertically rather than in a direction perpendicular to the selected line. For lines which are closer to vertical than to horizontal, the line width is applied horizontally.

9. The Windows Menu




To bring a particular window into view, select its corresponding menu item in the 'Windows' menu.

Appendix A: The Algorithms




Introduction



This Appendix is broken up into two parts. The first part deals with computations from compressed Stokes matrix data (JPL AIRSAR). The second part deals with computations made from byte images.

Sigma0 was written in Macintosh Programmer's Workshop (MPW ) C version 3.3.1 and Macintosh Programmer's Workshop (MPW) version 3.3.1. Sigma0 also uses the XVT Development Solution for C which contains the XVT Portability Toolkit version 4.0 and XVT Design version 3.0. It is the XVT software that allows the Sigma0 program to be compiled for the Mac or the PC. The XVT products come from XVT Software Inc. in Boulder, Colorado. All of the equations and algorithms listed in this appendix are written in C. All pseudo-code will be written in italics.

Compressed Stokes Matrix Data



Image Geometry

AIRSAR data (or compressed Stokes matrix data) is expected to be in range line format. So in the following image, range increases from top to bottom. Since the AIRSAR is a left-looking sensor, near azimuth is on the right side of the image and far azimuth is on the left.





In addition, the data can be in a slant range or a ground range projection. In a ground range projection, the pixels are defined as having uniform spacing in the range and azimuth directions on the ground. In the slant range projection, the pixels have uniform spacing in the slant range and azimuth directions. The following diagrams may help clarify the difference:





The Stokes matrix

To compute the 4 x 4 real Stokes matrix elements, we must first read the general scale factor from the "old" header. The general scale factor is assumed to be stored as text in the 133rd field of the "old" header (assuming the first field is numbered 1).

Two lookup arrays are calculated to reduce the number of computations required for synthesizing images:
sc0
and
sc1
. The array
sc0
is of type extended and contains 160 elements. It is initialized as follows:

variables:
	extended e		
- temporary variable

	extended sc0[160]	
- lookup array 0

	int i			
- looping variable


algorithm:
	e = pow (2.0,-100.0);
		for (i=-100; i<60; i++) {
		sc0[i+100] = e;
		e *= 2.0;
	}

The array
sc1
is of type extended and contains 256 elements and is initialized as follows:

variables:
	extended sc1[256]	
- lookup array 1

	extended gen_sca	
- general scale factor

	int i			
- looping variable


algorithm:
	for (i=-128; i<128; i++) 
		sc1[i+128] = (i/254.0 + 1.5)*scale;

Assuming that the 10 bytes we wish to uncompress are stored in the char array
b[10]
, we can now calculate the (1,1) element of the Stokes matrix as follows:

variables:
	char b[10]		
- contains the 10 bytes of compressed data for 1 pixel

	extern extended sc0[]	
- previous initialized lookup array
	
	extern extended sc1[]	
- previous initialized lookup array

	extended p11		
- contains (1,1) element of Stokes matrix


algorithm:
	if (b[0]<-100) b[0] = -100;
	if (b[0]>59) b[0] = 59;
	p11 = sc0[b[0]+100]*sc1[b[1]+128];

Use the following to calculate the remaining elements of the Stokes matrix:

variables:
	char b[10]  	
- contains the 10 bytes of compressed data for 1 pixel

	extended p[16]  	
- contains the 4 x 4 Stokes matrix

	extended p11	
- contains the previously calculated (1,1) element


algorithm:
	p[0] = p11;                        // element 1,1
	p[1] = b[2]/127.0;                 // 1,2
	p[2] = b[3]*b[3]/16129.0;
	if (b[3] < 0) p[2] = -p[2];        // 1,3
	p[3] = b[4]*b[4]/16129.0;
	if (b[4] < 0) p[3] = -p[3];        // 1,4
	p[6] = b[5]*b[5]/16129.0;
	if (b[5] < 0) p[6] = -p[6];        // 2,3
	p[7] = b[6]*b[6]/16129.0;
	if (b[6] < 0) p[7] = -p[7];        // 2,4
	p[10] = b[7]/127.0;                // 3,3
	p[11] = b[8]/127.0;                // 3,4
	p[15] = b[9]/127.0;                // 4,4
	p[5]  = p[0]-p[10]-p[15];          // 2,2
	p[4]  = p[1];                      // 2,1
	p[8]  = p[2];                      // 3,1
	p[12] = p[3];                      // 4,1
	p[9]  = p[6];                      // 3,2
	p[13] = p[7];                      // 4,2
	p[14] = p[11];                     // 4,3

Basic calculations

The parameters required to generate the various images are calculated as follows:

	
parameter
		
in dBs


	TP = p11		10 log (TP)
	HH = p11+p22+2p12	10 log (HH)
	VV = p11+p22-2p12	10 log (VV)
	HV = p11-p22	10 log (HV)
	RL = p11-p44	10 log (RL)
	RR = p11+p44+2p14	10 log (RR)
	|HHVV*| =		10 log (|HHVV*|)
	   |(p33-p44,-2p34)|

	HHVV* phase = 	N/A
	   tan-1(-2p34/(p33-p44)
	|HHHV*| =		10 log (|HHHV*|)
	   |(p13+p23,-p14-p24)|
	HHHV* phase =	N/A
	   tan-1((-p14-p24)/(p13+p23)
	|HHHV*| =		10 log (|HHHV*|)
	   |(p13+p23,-p14-p24)|
	HHHV* phase =	N/A
	   tan-1((-p14-p24)/(p13+p23)
	correlation coefficient =	N/A
	   |HHVV*|/(sqrt(HH) sqrt(VV))
	

The function |(a,b)| is calculated as sqrt(a*a+b*b) where (a,b) represents a complex number with a being the real component and b being the imaginary component.

Image generation (TP, HH, HV, VV, RL, RR)

To generate a total power, HH, HV, VV, RL, or RR image, a representative histogram must first be generated. To do so, the maximum and minimum values of the parameter being displayed are found:

variables:
	int start_line	
- starting line number to examine

	int skip_line	
- number of lines to skip

	short line,samp	
- coordinates of sample pixel

	short xsize,ysize	
- x and y dimensions of the image

	extended max	
- variable to store maximum value

	extended min	
- variable to store minimum value

	extended value	
- parameter being calculated (e.g. HH)


algorithm:
	start_line = ysize/10;
	skip_line = (ysize-start_line)/8;
	for (line=start_line; line<ysize; line+=skip_line) {
		for (samp=0; samp<xsize; samp+=10) {
			get the 10 compressed bytes for pixel (samp,line)

			value = parameter being calculated (e.g. HH)

			if (value < 0.0) value = 0.0;
			if (line == start_line && samp == 0) {
			   max = value;
			   min = value;
			}
			if (value > max) max = value;
			if (value < min) min = value;
		}
	}

Note that in the above, the first 10% of the image lines are skipped. It is assumed that the data in the near range may be quite saturated. Also, only 8 lines and every 10 pixels in each line are used to find the maximum and minimum values as well as the representative histogram.

The representative histogram containing 256 points is calculated as follows:

variables:
	short line,samp	
- coordinates of sample pixel

	short xsize,ysize	
- x and y dimensions of the computed image

	int start_line	
- start_line used before

	int skip_line	
- skip_line used before

	int k			
- histogram bin and looping variable

	extended value	
- the parameter being calculated

	extended max	
- maximum value found previously

	extended min	
- minimum value found previously

	extended bin	
- bin size

	short hist[256]	
- histogram being generated


algorithm:
	bin = (max-min) / 256.0;
	for (k=0; k<256; k++) hist[k] = 0;
	for (line=start_line; line<ysize; line+=skip_line) {
		for (samp=0; samp<xsize; samp+=10) {
			get the 10 compressed bytes for pixel (samp,line)

			value = parameter being calculated (e.g. HH)

			if (value < 0.0) value = 0.0;
			k = floor((value-min)/bin);
			if (k <= 0) k = 0;
			if (k >= 256) k = 255;
			hist[k]++;
		}
	}

Using the generated histogram, the user then adjusts the values of
max
and
min
. All values >=
max
will be converted to pixel value 255 and all values <=
min
will be converted to pixel value 0.

After the user has adjusted the
max
and
min
values, the image can be generated as follows:

variables:
	short line,samp	
- coordinates of sample pixel

	short xsize,ysize	
- x and y dimensions of the computed image

	int theint		
- the output pixel value

	int thesigma	
- the output sigma0 value

	extended value	
- the parameter being calculated

	extended max	
- maximum value found previously

	extended min	
- minimum value found previously

	extended scale	
- scale factor to convert to byte values


algorithm:
	scale = 255.0 / (max-min);
	for (line=0; line<ysize; line++) {
		for (samp=0; samp<xsize; samp++) {
			get the 10 compressed bytes for pixel (samp,line)

			value = parameter being calculated (e.g. HH)

			if (value < 0.0) value = 0.0;
			theint = (value-min)*scale;
			if (theint>255) theint = 255;
			if (theint<0) theint = 0;
			value = (value==0.0) ? -100 : 10.0*log10 (value);
			if (value >= 0.0) thesigma = value+0.5;
			else thesigma = value-0.5;
			if (thesigma < -99) thesigma = -100;
			if (thesigma > 99) thesigma = 99;
		}
	}

In the above,
theint
is the output pixel value and
thesigma
is the parameter being calculated in dBs and rounded to the nearest integer.
Thesigma
is the parameter which is displayed in the window when 'Display sigma0' is selected from the 'Image' window. For the total power, HH, HV, VV, RL, and RR images, this is also the value shown as the third parameter in the lower left corner of the image window.

Image generation (HHVV*, HHHV*, HVVV*)

To generate an HHVV*, HHHV*, or HVVV* image, a representative histogram of the magnitude of the parameter must first be generated. To do so, the maximum and minimum values of the magnitude of the parameter being displayed are found:

variables:
	int start_line	
- starting line number to examine

	int skip_line	
- number of lines to skip

	short line,samp	
- coordinates of sample pixel

	short xsize,ysize	
- x and y dimensions of the image

	extended max	
- variable to store maximum value

	extended min	
- variable to store minimum value

	extended value	
- parameter being calculated (e.g. HH)


algorithm:
	start_line = ysize/10;
	skip_line = (ysize-start_line)/8;
	for (line=start_line; line<ysize; line+=skip_line) {
		for (samp=0; samp<xsize; samp+=10) {
			get the 10 compressed bytes for pixel (samp,line)

			value = magnitude of parameter being calculated

		            (e.g. |HHHV*|)

			if (line == start_line && samp == 0) {
			   max = value;
			   min = value;
			}
			if (value > max) max = value;
			if (value < min) min = value;
		}
	}

The representative histogram containing 256 points is calculated as follows:

variables:
	short line,samp	
- coordinates of sample pixel

	short xsize,ysize	
- x and y dimensions of the computed image

	int start_line	
- start_line used before

	int skip_line	
- skip_line used before

	int k			
- histogram bin and looping variable

	extended value	
- the magnitude

	extended max	
- maximum value found previously

	extended min	
- minimum value found previously

	extended bin	
- bin size

	short hist[256]	
- histogram being generated


algorithm:
	bin = (max-min) / 256.0;
	for (k=0; k<256; k++) hist[k] = 0;
	for (line=start_line; line<ysize; line+=skip_line) {
		for (samp=0; samp<xsize; samp+=10) {
			get the 10 compressed bytes for pixel (samp,line)

			value = magnitude of parameter being calculated

		            (e.g. |HHHV*|)

			k = floor((value-min)/bin);
			if (k <= 0) k = 0;
			if (k >= 256) k = 255;
			hist[k]++;
		}
	}

Using the generated histogram, the user then adjusts the values of
max
and
min
. All values >=
max
will be converted to pixel value 255 and all values <=
min
will be converted to pixel value 0.

In order to calculate arctangents quickly, a lookup table is generated. The table
sc2
is an extended array of size 45.

variables:
	int i			
- looping variable

	extended sc2[45]	
- the tangent lookup table


algorithm:
	for (i=0; i<45; i++) 
		sc2[i] = tan((float)i*3.141592654/90.0);

Note that the array spans the interval [0, PI/2) radians in increments of 2 degrees.

To estimate the arctangent of a complex number (a,b), the absolute value of the ratio b/a is calculated. The lookup array is then searched for the element which is closest to the ratio. The result is an integer from 0 to 44. This integer value is then corrected depending on the quadrant in the imaginary plane in which (a,b) falls. The integer is then converted to an extended value from 0.0 to 2*PI. The algorithm is as follows:

variables:
	extended x		
- the absolute value of the ratio (imag/real)

	extended real	
- the real component of the complex number

	extended imag	
- the imaginary component of the complex number

	extended phase	
- the output phase in radians

	int start		
- the start index for searching

	int end		
- the end index for searching

	int mid		
- the midpoint between start and end

	int n			
- the selected index


algorithm:
	if (imag == 0.0 && real == 0.0) return 0.0;
	if (real == 0.0 && imag >  0.0) return 1.570796327;
	if (real == 0.0 && imag <  0.0) return 4.71238898;

	x = fabs (imag/real);

	if (x > sc2[44])  n = 45;
	else {
		n = -1;
		start = 0;
		end = 44;
		mid = (start+end)/2;
		while (n == -1) {
			if (x == sc2[mid]) n = mid;
			else if (x < sc2[mid]) end = mid;
			else start = mid;
			if (end-start == 1) {
				if ((sc2[end]-x) > (x-sc2[start])) n = start;
				else n = end;
			} else mid = (start+end)/2;
		}	
	}

	if (real < 0.0) n = 90 - n;
	if (imag < 0.0) n = 180 - n;

	phase = (float)n*3.141592654/90.0;

The image can now be calculated. Note that for complex images, the magnitude is stored in the least significant 4 bits and the phase is stored in the most significant 4 bits. Of course, an appropriate color table must be used to display the image using this coding scheme. Color tables are described later in this Appendix. The image is generated as follows:

variables:
	short line,samp	
- coordinates of sample pixel

	short xsize,ysize	
- x and y dimensions of the computed image

	int theint		
- the output pixel value

	int themag		
- the magnitude

	int thesigma	
- the output sigma0 value in dBs

	int thephase	
- the phase/2 in degrees

	extended a		
- real component

	extended b		
- imaginary component

	extended value	
- the magnitude

	extended phase	
- the phase (0.0 -> 2*PI)

	extended max	
- maximum value found previously

	extended min	
- minimum value found previously

	extended scale	
- scale factor to convert magnitude to 0 -> 15


algorithm:
	scale = 15.0 / (max-min);
	for (line=0; line<ysize; line++) {
		for (samp=0; samp<xsize; samp++) {
			get the 10 compressed bytes for pixel (samp,line)

			a = real component of parameter being calculated

			   (e.g. HHHV*)

			b = imaginary component of parameter being 

			   calculated (e.g. HHHV*)


			/* -- calculate phase and magnitude -- */
			value = sqrt(a*a+b*b);
			phase = myatan (b,a);   // 0 -> 2*PI

			/* -- convert magnitude to 0->15 -- */
			theint = (value-min)*scale;
			if (themag>15) themag = 15;
			if (themag<0) themag = 0;

			/* -- convert phase to 0->15 -- */
			phase *= 2.387324146;
			thephase = phase;
			if (thephase>15) thephase = 15;
			if (thephase< 0) thephase = 0;

			/* -- calculate output pixel -- */
			theint = themag + (thephase<<4);

			/* -- calculate magnitude in dBs -- */
			value = (value==0.0) ? -100 : 10.0*log10 (value);
			if (value >= 0.0) thesigma = value+0.5;
			else thesigma = value-0.5;
			if (thesigma < -99) thesigma = -100;
			if (thesigma > 99) thesigma = 99;

			/* -- calculate phase in degrees/2 -- */
			phase *= 12.0;
			if (phase > 90.0) phase += -180.0;
			if (phase >= 0.0) thephase = phase+0.5;
			else thephase = phase-0.5;
			if (thephase < -90) thephase = -90;
			if (thephase > 90) thephase = 90;
		}
	}

In the above,
theint
is the output pixel value.
Thesigma 
is the magnitude calculated in dBs and rounded to the nearest integer.
Thesigma
is the parameter which is displayed in the window when 'Display sigma0' is selected from the 'Image' window.
Thephase
is the value shown as the third parameter in the lower left corner of the image window. Before being displayed, it is automatically multiplied by 2.

Also in the above, the function
myatan
is the name of the routine which searches the tangent lookup table as described previously.

Image generation (HHVV* phase)

To generate an HHVV* phase image, the following algorithm is used:

variables:
	short line,samp	
- coordinates of sample pixel

	short xsize,ysize	
- x and y dimensions of the computed image

	int thephase	
- the phase

	extended a		
- real component

	extended b		
- imaginary component

	extended phase	
- the phase


algorithm:
	scale = 255.0 / (max-min);
	for (line=0; line<ysize; line++) {
		for (samp=0; samp<xsize; samp++) {
			get the 10 compressed bytes for pixel (samp,line)

			a = real component of HHVV*

			b = imaginary component of HHVV*


			/* -- calculate phase -- */
			phase = myatan (b,a);   // 0 -> 2*PI

			/* -- convert phase to 0->255 -- */
			phase *= 40.58451049;
			theint = phase;
			if (theint>255) theint = 255;
			if (theint<  0) theint = 0;

			/* -- calculate phase in degrees/2 -- */
			phase *= 0.705882352;
			if (phase > 90.0) phase += -180.0;
			if (phase >= 0.0) thephase = phase+0.5;
			else thephase = phase-0.5;
			if (thephase < -90) thephase = -90;
			if (thephase > 90) thephase = 90;
		}
	}

In the above,
theint
is the output pixel value.
Thephase
is the value shown as the third parameter in the lower left corner of the image window and is the value shown when 'Display phase' is selected from the 'Image' menu . Before being displayed, it is automatically multiplied by 2.

Image generation (correlation coefficients of HH-VV, HH-HV, HV-VV)

To generate a correlation coefficient image, the following algorithm is used:

variables:
	short line,samp	
- coordinates of sample pixel

	short xsize,ysize	
- x and y dimensions of the computed image

	int theint		
- the output pixel

	int theCC		
- the correlation coefficient*100

	extended a		
- real component

	extended b		
- imaginary component

	extended r		
- the correlation coefficient

	extended value	
- either HH or VV, either HH or HV, either HV or VV


algorithm:
	scale = 255.0 / (max-min);
	for (line=0; line<ysize; line++) {
		for (samp=0; samp<xsize; samp++) {
			get the 10 compressed bytes for pixel (samp,line)

			a = real component of HHVV* or HHHV* or HVVV*

			b = imaginary component of HHVV* or HHHV* or HVVV*


			r = sqrt(a*a + b*b);

			value = HH or HV

			if (value > 0.0) r /= sqrt(value);
			else r = 0.0;

			value = VV or HV 

			if (value > 0.0) r /= sqrt(value);
			else r = 0.0;

			theint = 255.0*r;
			if (theint > 255) theint = 255;
			if (theint < 0  ) the int = 0;

			theCC = 100*r;
			if (theCC > 100) theCC = 100;
			if (theCC > 0  ) theCC = 0;
		}
	}


In the above,
theint
is the output pixel value.
TheCC
is the value shown when 'Display corr coef' is selected from the 'Image' menu and is also the third parameter shown in the lower left corner of the image window.

Calculation of Incidence Angle

The incidence angle is calculated each time the user selects the 'Mean and std dev' menu item for a Stokes image. It is calculated differently depending on the image geometry. If the selected area is one or more rectangles or a line, then the mid-point of the selected rectangle or the line is calculated (note that the incidence angle is only a function of the y coordinate). The following summarizes the incidence angle value calculated as a function of selection type:

selection type incidence angle calculated

rectangle incidence angle at center of rectangle
line incidence angle at center of line
polygon mean incidence angle

The algorithm for calculating the center of the selected rectangle or the selected line follows:

variables:
	Rect rect		
- selected rectangle

	Rect line		
- selected line

	int y			
- the range line in "original" image coordinates

	int averaging	
- amount of averaging (from variable format header)

	int uly		
- upper left y coord (from variable format header)


algorithm:
	if selected area is a rectangle

		y = (rect.top + rect.bottom)/2;
	else if selected area is a line

		y = (line.top + line.bottom)/2;
	y = y*averaging + uly

Both the selected rectangle and the selected line are stored in the same type of data structure, a rectangle. For the selected line, one endpoint is stored as (line.left, line.right) and the other endpoint is stored in (line.right, line.bottom). For the selected rectangle, one corner is stored as (rect.left, rect.right) and the opposite corner is stored as (rect.right, rect.bottom).

The incidence angle is calculated as follows:

variables:
	extended nearrange	
- near range (read from old header)

	extended altitude		
-altitude (read from old header)

	extended incidence_angle
- the output incidence angle (in radians)

	extended groundrange	
- distance to range line y in ground range geometry

	extended slantrange	
- distance to range line y in slant range geometry

	extended rspace		
- range pixel spacing (from variable format header)

	int y				
- range line coordinate (from before)


algorithm:
	if ground range projection
 {
		if (nearrange <= altitude) incidence_angle = -1.0;
		else {
			groundrange = sqrt (nearrange*nearrange-altitude*
				altitude)
			groundrange += rspace*(extended)y
			incidence_angle = atan (groundrange/altitude);
		}
	} else {
		slantrange = nearrange + rspace*(extended)y;
		if (slantrange <= altitude) incidence_angle = -1.0;
		else {
			incidence_angle = acos (altitude/slantrange);
		}
	}

An incidence angle of value = -1.0 indicates that the geometry was invalid.

If the selected area is a polygon, then a mean incidence angle is calculated rather than the incidence angle of the center of the selection. To do so, the smallest rectangle enclosing the polygon is calculated and saved in
rect
. The following algorithm is used to calculate the mean incidence angle:

variables
	Rect rect			
- smallest rectangle enclosing selected polygon

	long count			
- counter for # of enclosed pixels

	extended sum_angle	
- incidence angle accumulator

	extended incidence_angle
- current incidence angle

	short line			
- current line

	short sample		
- current sample


algorithm:
	count = 0;
	sum_angle = 0;
	for (line=rect.top; line<=rect.bottom; line++) {
		incidence_angle = calculated incidence angle for line

			y = line*averaging + uly

		for (sample=rect.left; sample<=sample.right; sample++) {
			if (incidence_angle != -1.0 && 
			    sta_PtInRegion(sample, line)) {
				count++;
				sum_angle += incidence_angle;
			}
		}
	}
	if (count > 0) incidence_angle = sum_angle/(extended)count;

The function
sta_PtInRegion 
is described in the next section. Note that because the incidence angle only varies as a function of line, it is calculated once per line and accumulated the appropriate number of times for each line.

Note that the incidence angle reported in the corner reflector analysis results is NOT that of the pixel with the largest total power value. It is the incidence angle of the pixel corresponding to
((rect.right + rect.left)/2, (rect.top + rect.bottom)/2)
where
rect
contains the selection rectangle.

Note also that the altitude is normally read from field 132 of the old header. If this field does not exist or if the value is <= 0.0, then the old header is searched for the first occurence of "RADAR ALTITUDE (M" or "ALTITUDE (M".

Calculation of statistics

To more quickly calculate the statistics of the selected area, the smallest rectangle which encompasses the selected region (including multiple rectangles) is found. This encompassing rectangle is stored in a variable we'll call theFrame. An additional function must be implemented which determines whether a given point is actually within a selected area. This function is called PtInSelected.

The following statistics are calculated as appropriate for JPL AIRSAR data:

parameter statistics calculated

TP, RL, RR mean, relative standard deviation
HH, HV, VV mean, relative standard deviation
|HHVV*|, |HHHV*|,|HVVV*| mean, relative standard deviation
HHVV* phase, HHHV* phase mean, standard deviation
HVVV* phase
correlation coefficients mean, relative standard deviation

The method of calculating statistics depends on the parameter being measured. The following sub sections describe how all of the possible statistics are calculated.

Note: If for some reason no pixels were selected by the user (even though a selection region was specified), the values shown in the statistics window will be invalid.

TP, HH, HV, VV, RL, RR, |HHVV*|, |HHHV*|, |HVVV*|


The mean and relative standard deviations are calculated as follows:

variables:
	short line,samp	
- coordinates of sample pixel

	Rect theframe	-
the rectangle within which the selected areas lie

	extended value	
- the parameter being calculated

	extended mean	
- the mean

	extended stddev	
- the standard deviation

	extended relstddev
- the relative standard deviation

	int n 		
- the number of selected pixels


algorithm:
	mean = stddev = 0.0;
	n = 0;
	for (line=theFrame.top; line<=theFrame.bottom; line++) {
		for (samp=theFrame.left; samp<=theFrame.right; samp++) {
			if (sta_PtInRegion(samp, line)) {
				get the 10 compressed bytes for 

				   pixel (samp,line)

				value = parameter being calculated 

				   (e.g. HH or |HHVV*|)

				if (value < 0.0) value = 0.0;
				mean += value;
				stddev += value*value;
				n++;
			}
		}
	}
	if (n > 0) {
		mean /= (extended)n;
		stddev /= (extended)n;
		stddev -= mean*mean;
		stddev = (stddev > 0.0) ? sqrt(stddev) : 0.0;
		relstddev = (mean != 0.0) ? (mean+stddev)/mean : 0.0;
	}

HHVV* phase, HHHV* phase, HVVV* phase


The mean phase is calculated first:

variables:
	short line,samp	
- coordinates of sample pixel

	Rect theframe	
- the rectangle within which the selected areas lie

	extended a		
- the real component

	extended b		
- the imaginary component

	extended suma	
- the accumulator for the real component

	extended sumb	
- the accumulator for the imaginary component

	extended mean	
- the mean phase

	extended stddev	
- the standard deviation

	int n 		
- the number of selected pixels


algorithm:
	suma = sumb = 0.0;
	n = 0;
	for (line=theFrame.top; line<=theFrame.bottom; line++) {
		for (samp=theFrame.left; samp<=theFrame.right; samp++) {
			if (sta_PtInRegion(samp, line)) {
				get the 10 compressed bytes for 

				   pixel (samp,line)

				a = real component of, say, HHVV*

				b = imaginary component of, say, HHVV*

				suma += a;
				sumb += b;
				n++;
			}
		}
	}
	mean = atan2(sumb,suma); // -PI -> PI
	mean *= 57.29577951;     // -180 -> 180

Now the standard deviation of the phase is calculated as follows:

variables:
	short line,samp	
- coordinates of sample pixel

	Rect theframe	
- the rectangle within which the selected areas lie

	extended a		
- the real component

	extended b		
- the imaginary component

	extended mean	
- the mean phase (calculated previously)

	extended stddev	
- the standard deviation

	extended phase	
- the phase of each pixel

	int n 		
- the number of selected pixels (found previously)


algorithm:
	stddev = 0.0;
	for (line=theFrame.top; line<=theFrame.bottom; line++) {
		for (samp=theFrame.left; samp<=theFrame.right; samp++) {
			if (sta_PtInRegion(samp, line)) {
				get the 10 compressed bytes for 

				   pixel (samp,line)

				a = real component of, say, HHVV*

				b = imaginary component of, say, HHVV*

				phase = atan2 (b,a);   // -PI -> PI
				phase *= 57.29577951;  // -180 -> 180 deg
				phase = mean - phase;
				if (phase < 0.0) phase = -phase;
				if (360.0-phase < phase) phase = 360-phase;
				stddev += phase*phase;
			}
		}
	}
	if (n > 0) {
		stddev /= (extended)n;
		stddev = (stddev > 0.0) ? sqrt(stddev) : 0.0;
	}

Correlation coefficient


The mean HHVV*, HHHV* or HVVV* value must be calculated first:

variables:
	short line,samp	
- coordinates of sample pixel

	Rect theframe	
- the rectangle within which the selected areas lie

	extended a		
- the real component of HHVV*, HHHV*, or HVVV*

	extended b		
- the imaginary component of HHVV*, HHHV*, or HVVV*

	extended meana	
- the accumulator for the real component

	extended meanb	
- the accumulator for the imaginary component

	int n 		
- the number of selected pixels


algorithm:
	suma = sumb = 0.0;
	n = 0;
	for (line=theFrame.top; line<=theFrame.bottom; line++) {
		for (samp=theFrame.left; samp<=theFrame.right; samp++) {
			if (sta_PtInRegion(samp, line)) {
				get the 10 compressed bytes for 

				   pixel (samp,line)

				a = real component of HHVV*, HHHV*, or HVVV*

				b = imag component of HHVV*, HHHV*, or HVVV*

				meana += a;
				meanb += b;
				n++;
			}
		}
	}
	meana /= (extended)n;
	meanb /= (extended)n;

For the HH-VV correlation coefficient case, assuming that the mean HH and mean VV values have already been calculated, the mean correlation coefficient is calculated as:

	if (meanHH != 0.0 && meanVV != 0.0)
		meanCC = sqrt(meana*meana+meanb*meanb)/
		         sqrt(meanHH)/sqrt(meanVV);
	else 
		meanCC = 0.0;

Now the relative standard deviation of the correlation coefficient is calculated as 
follows:

variables:
	short line,samp	
- coordinates of sample pixel

	Rect theframe	
- the rectangle within which the selected areas lie

	extended a		
- the real component of HHVV*

	extended b		
- the imaginary component of HHVV*

	extended meanCC	
- the mean corr coef (calculated previously)

	extended stddev	
- the standard deviation

	extended relstddev
- the relative standard deviation

	extended value	
- the HH or VV value of each pixel

	extended r		
- the correlation coefficient of each pixel

	int n 		
- the number of selected pixels (found previously)


algorithm:
	stddev = 0.0;
	for (line=theFrame.top; line<=theFrame.bottom; line++) {
		for (samp=theFrame.left; samp<=theFrame.right; samp++) {
			if (sta_PtInRegion(samp, line)) {
				get the 10 compressed bytes for 

				   pixel (samp,line)

				a = real component of, say, HHVV*

				b = imaginary component of, say, HHVV*

				r = sqrt(a*a+b*b);

				value = HH

				if (value > 0.0) r /= sqrt(value);
				else r = 0.0;

				value = VV

				if (value > 0.0) r /= sqrt(value);
				else r = 0.0;

				stddev += r*r;
			}
		}
	}
	if (n > 0) {
		stddev /= (extended)n;
		stddev -= meanCC*meanCC;
		stddev = (stddev > 0.0) ? sqrt(stddev) : 0.0;
		relstddev = (meanCC != 0.0) ? (meanCC+stddev)/meanCC :

Incidence Angle


The incidence angle is calculated exactly as described in the "Calculation of Incidence Angle" section for compressed Stokes matrix data.

Histogram Generation


The histogram is generated as the statistics are being calculated. It is updated differently depending on the polarization of the displayed image. For most parameters (TP, HH, VV, HV, RL, RR, HHVV*, HHHV*, HVVV*), the histogram is generated as follows:

variables:
	extended hist[256]	
- normalized histogram (output)

	short i			
- looping variable (internal)

	extended value		
- TP, HH, VV, HV, RL, RR, |HHVV*|, |HHHV*|, or
|HVVV*| (internal)

	int theInt			
- integerized version of value in dBs (internal)

	extended total		
- integrated sum of histogram (internal)


algorithm:
	for (i=0; i<256; i++) hist[i] = 0.0;
	while looping over selected region
 {
		if current pixel is in selected region
 {
			value = TP, HH, etc. or |HHVV*|, etc. as

				appropriate

			theInt = (value > 0.0) ? 10.0 * log10 (value) :
				-100;
			if (theInt > 99) theInt = 99;
			if (theInt < -100) theInt = -100;
			hist[intInt] ++;
		}
	}
	total = 0.0;
	for (i=0; i<256; i++) total += hist[i];
	for (i=0; i<256; i++) hist[i] /= total;

When this histogram is displayed in the statistics window, only those values from -50 to +24 dB are shown (i.e. indices 50 to 124).

If the displayed image is an HHVV* phase image, then the histogram is generated as follows:

variables:
	extended hist[256]	
- normalized histogram (output)

	short i			
- looping variable (internal)

	extended phase		
- HHVV* phase (internal)

	int theInt			
- integerized version of value in dBs (internal)

	extended total		
- integrated sum of histogram (internal)


algorithm:
	for (i=0; i<256; i++) hist[i] = 0.0;
	while looping over selected region
 {
		if current pixel is in selected region
 {
			phase = HHVV* phase (0 -> 2
p
)

			phase *= 28.64788976; // rad -> deg
			if (phase > 90.0) phase -= 180.0;
			theInt = phase;
			if (theInt < -90) theInt = -90;
			if (theInt >  90) theInt = 90;
			hist[intInt+90] ++;
		}
	}
	total = 0.0;
	for (i=0; i<256; i++) total += hist[i];
	total *= 2.0;
	for (i=0; i<256; i++) hist[i] /= total;


Note the histogram is valid only for indices 0 to 180 inclusive. When this histogram is displayed in the statistics window, only those values from -90 to 90 degrees are shown (i.e. indices 0 to 180).

If the displayed image is a correlation coefficient image, then the histogram is generated as follows:

variables:
	extended hist[256]	
- normalized histogram (output)

	short i			
- looping variable (internal)

	extended r			
- correlation coefficient (internal)

	int theInt			
- integerized version of value in dBs (internal)

	extended total		
- integrated sum of histogram (internal)


algorithm:
	for (i=0; i<256; i++) hist[i] = 0.0;
	while looping over selected region
 {
		if current pixel is in selected region
 {
			r = correlation coefficient (0.0->1.0)

			r *= 100; // 0.0 -> 100.0
			theInt = r;
			if (theInt < 0) theInt = 0;
			if (theInt > 100 theInt = 100;
			hist[intInt]++;
		}
	}
	total = 0.0;
	for (i=0; i<256; i++) total += hist[i];
	total *= 0.01;
	for (i=0; i<256; i++) hist[i] /= total;


The histogram is valid only for indices 0 to 100 inclusive. When this histogram is displayed in the statistics window, only those values from 0.0 to 1.0 are shown (i.e. indices 0 to 100).

Mouse Tracking


As the mouse is moved over the image window, the current pixel location and an appropriate value is displayed in the lower left corner.

The sample and line of the current pixel are displayed in the image window. Recall that coordinates range from 0 to (n_samples-1) in the sample direction (horizontal) and 0 to (n_lines -1) in the line direction (vertical). The (0,0) origin is in the upper left corner of the image. Sample numbers increase to the right and line numbers increase downward.

The third value is the byte pixel value (also called dn). The fourth value displayed depends on the image type. If the image type is total power, HH, HV, VV, RL, or RR, then the appropriate value is computed (see "Basic Calculations" for compressed Stokes matrix data) and converted to dBs. The value in dBs is converted to an integer from -100 to 99 and saved as a signed byte:

variables:
	extended value		
- HH, HV, RL, etc. NOT in dBs (input)

	extended valueDB		
- value converted to dBs (internal)

	int theInt			
- valueDB integerized (internal)

	signed char outByte	
- theInt converted to signed char (output)


algorithm:
	valueDB = (value > 0.0) ? 10.0 * log10 (value) : -100.0;
	theInt = (valueDB > 0.0) ? valueDB + 0.5 : value - 0.5;
	if (theInt < -99) theInt = -100;
	if (theInt > 99) theInt = 99;
	outByte = (signed char)theInt;

The addition and subtraction of 0.5 from
valueDB
is for rounding purposes.
outByte
is the third value displayed for image types of total power, HH, HV, RL, or RR.

If the image type is HHVV*, HHVV* phase, HHHV*, or HVVV*, then the phase of the complex value is converted from 0 to 2p radians to -90 to 90 (instead of -180 to 180 degrees, which wouldn't fit into one byte):

variables:
	extended phase		
- 0 to 2p radians (input)

	extended phaseDeg		
- phase converted to -90.0 to 90.0 (internal)

	int theInt			
- phaseDeg converted integer (internal)

	signed char outByte	
- theInt converted to signed char (output)


algorithm:
	phaseDeg = phase * 28.64788972;
	if (phaseDeg > 90.0) phaseDeg += (-180.0);
	theInt = (phaseDeg >= 0.0) ? phaseDeg+0.5 : phaseDeg-0.5;
	if (theInt < -90) theInt = -90;
	if (theInt > 90) theInt = 90;
	outByte = (signed char)theInt;


Thus phase is quantized to 2 degrees. The third value displayed in the image window is
outByte
*2.

If the image type is correlation coefficient, then correlation coefficient is converted from 0.0 to 1.0 to 0 to 100 and stored one signed byte:

variables:
	extended r			
- correlation coefficient (input)

	extended rBig		
- r*100.0 (internal)

	int theInt			
- rBig converted integer (internal)

	signed char outByte	
- theInt converted to signed char (output)


algorithm:
	rBig = r*100.0;
	if (rBig > 100.0) rBig = 100.0;
	if (rBig < 0.0) rBig = 0.0;
	theInt = rBig + 0.5;
	outByte = (signed char)theInt;


The addition of 0.5 is for rounding purposes. The third parameter shown for correlation coefficient is
outByte
(i.e. correlation coefficient * 100).

Overlaid Values


If the currently displayed image is total power, HH, HV, VV, RL, or RR, then the signed char value stored for mouse tracking (
outByte
) is used as the number overlayed on zoomed-in pixels.

If the displayed image is HHVV*, HVVV*, or HHHV*, then the magnitude of the complex value is converted to a signed char using exactly the same equations as were used for mouse tracking for total power, HH, HV, VV, RL, or RR images.

If the displayed image is HHVV* phase, then the values superimposed on the zoomed-in pixels are the quantized phase calculated for mouse tracking times 2 (i.e.
outByte
*2).

If the displayed image is a correlation coefficient image, then the values superimposed on the zoomed-in pixels are the correlation coefficients times 100 (i.e.
outByte
) as calculated for mouse tracking.

Byte Images



Calculation of statistics

The only statistics calculated for byte images are the mean and standard deviation of the selected region. To calculate the statistics, the smallest rectangle enclosing all selected areas is first found. This rectangle is stored in
theFrame
. Statistics are then calculated as follows:

variables:
	short line		
- current line

	short samp		
- current sample

	int n			
- number of selected pixels

	Rect theFrame	
- smallest enclosing rectangle of selected areas

					
(calculated previously)

	extended mean	
- mean

	extended stddev	
- standard deviation

	int theint		
- pixel value converted to integer

	extended x		
- pixel value converted to extended


algorithm:
	n = 0;
	mean = stddev = 0.0;
	for (line=theFrame.top; line<=theFrame.bottom; line++) {
		for (samp=theFrame.left;samp=theFrame.right; samp++) {
			if (sta_PtInRegion(samp, line)) {
				n++;
				theint = pixel value
 & 255;
				x = (extended)theint;
				mean += x;
				stddev += x*x;
			}
		}
	}
	if (n > 0) {
		mean /= (extended)n;
		stddev = stddev/(extended)n - mean*mean;
		stddev = (stddev > 0.0) ? sqrt(stddev) : 0.0;
	}

Note that the function
sta_PtInRegion()
has been described previously as returning true if the given coordinate is within the currently selected region(s). Also,
pixel value
is expected to be in the range 0 to 255 inclusive. If
pixel value
is interpreted as signed by the compiler, then by bit-wise ANDing the char with 255, the sign is effectively removed and the value is interpreted properly.

Note: If for some reason no pixels were selected by the user (even though a selection region was specified), the values shown in the statistics window will be invalid.

Histogram Generation


The histogram is generated as the statistics are being calculated.

variables:
	extended hist[256]	
- normalized histogram (output)

	short i			
- looping variable (internal)

	int theInt			
- integerized version of pixel value (internal)

	extended total		
- integrated sum of histogram (internal)


algorithm:
	for (i=0; i<256; i++) hist[i] = 0.0;
	while looping over selected region
 {
		if current pixel is in selected region
 {
			theInt = byte image value

			intInt = theInt & 255;
			hist[intInt] += 1.0;
		}
	}
	total = 0.0;
	for (i=0; i<256; i++) total += hist[i];
	for (i=0; i<256; i++) hist[i] /= total;


Mouse Tracking

The sample and line of the current pixel are displayed in the image window. Recall that coordinates range from 0 to (n_samples-1) in the sample direction (horizontal) and 0 to (n_lines -1) in the line direction (vertical). The (0,0) origin is in the upper left corner of the image. Sample numbers increase to the right and line numbers increase downward.

The value of the current pixel is also displayed in the image window. Pixel values range from 0 to 255 inclusive.

Overlaid Values

The values overlayed on zoomed-in pixels are the image pixel values which range from 0 to 255 inclusive.


	

Appendix B: Transferring

Data to the Macintosh



Data Transfer



Transferring JPL AIRSAR data to the Macintosh can be difficult due to large data volumes, slow transfer rates, and incompatible file formats. Generally, data is transferred electronically to the Macintosh via a computer network. For instance, using a terminal emulation program, you may be able to use "kermit" to transfer a file from a remote computer to your Macintosh. This method is can be quite slow and is therefore inappropriate for transferring large data sets. If your Macintosh is connected to a network via Ethernet and you have the appropriate software, you may be able to transfer complete data sets fairly quickly. You may also be able to read MS-DOS formatted files using Apple's File Exchange software.

Please consult your system administrator if you need assistance.

Data Reduction



It is often desirable to reduce the amount of data you are transferring to the Macintosh. You can do this by transferring only a selected portion of the original data set and/or by averaging the data set down to a smaller size. If any averaging is to be done, the averaging is performed on each element of the Stokes matrix.

The Fortran program "reduce.for" creates a smaller data set from a larger or "original" data set. The program is shown here at the end of this Appendix and is also provided as a text file on Disk 1. The smaller data set created by "reduce.for" is written into a new file. You may need to modify the program slightly in order for it to run on your system.

The program makes the following assumptions:

(1) The "original" data set contains a variable format header and an "old" header.
(2) The input data is in the same geometry as that of the original processor output.
(3) If the record length given in the variable format header is not an integer multiple of the physical record length of the file, then each record (i.e. the bytes required to synthesize one range line) in the input file is padded such that the next record begins at the beginning of a physical record. (Same goes for the output file).
(4) Variable format header is no larger than 1024 bytes.
(5) "Old" header is no larger than 8192 bytes.

On a VAX/VMS system, you would compile and link the program as follows:

$ for reduce
$ link reduce

Note that the "open" statement expects the record length to be in words (i.e. 4 bytes). In other environments, the record length is expected to be in bytes. Be sure to change the "open" statements as appropriate for your system.

To run the program on a VAX/VMS system, type "run reduce". The following is a sample session. The user's inputs are in boldface.

             <<< Reduce >>>

Enter input data file name -->
dud2:[data]cm3181l.dat


Enter input file physical record length (bytes) -->
10240


Samples in input file:         1024
Lines in input file:           1279

Enter width and height of output data 
(width must be multiple of 256) -->
256, 256


Enter amount of averaging (1..4)
(e.g. N = average every NxN pixels) -->
4


Enter x,y of upper left corner
((0,0)=uppermost left pixel) -->
0,0


Enter output file name -->
dud2:[data]cm3181l.small


Enter output file physical record length (bytes) -->
512


Writing variable header...

Storing old header...

Writing file...

line           0
...
line        1020
...done

The first input,
dud2:[data]cm3181l.dat
, is the name of the input data file. Since the program has no way of determining the physical record length of the file, the user must enter this. To determining this on a VAX/VMS system, you would use the "dir/full" command. The second input is the input file physical record length in bytes, e.g.
10240
. The program then reads the variable format header on the input file and determines the number of lines and samples in the data set.

The third input is the desired output dimensions of the file, e.g.
256, 256
.
The fourth input is the amount of averaging you want. Valid values are 1 through 4. If you select an averaging value of N, then the Stokes matrices of every N x N pixels are averaged to form one output Stokes matrix. The value selected above was
4
.

The fifth input is the coordinate of the first sample and line you want to extract and/or average from within the input data file, e.g.
0,0
.

The program now checks to make sure that the selected parameters make sense. If they do, then you are asked to enter the name of the output file, e.g.
dud2:[data]cm3181l.small
, followed by the output record length, e.g.
512
.

The program then writes the new file.

The following diagrams may help you understand how to select the averaging and upper left coordinate:





"Reduce.for" Program Listing



cccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c	PROGRAM:	reduce.for
c	AUTHORS:	Lynne Norikane
c	  		Howard Zebker
c
c	DESCRIPTION:
c
c	This program program allows you to store a subset
c	and/or averaged down version of an "original" JPL
c	AIRSAR data set into a separate file.  "Original"
c	implies that the geometry of the data is the same
c	as that of the original processor output.
c
c	The AIRSAR data MUST have both a variable format
c	header and an "old" header.
c
c	Variable format header fields 14 through 16 are
c	used to store the upper left (x,y) coordinates and
c	the averaging.  Note that this program will
c	overwrite anything which may already exist in
c	those fields.
c
c	The upper left corner of the original data set
c	corresponds to coordinate (0,0).
c
c	COPYRIGHT
c
c	Copyright (c) 1992, 1993, California Institute of
c	Technology.  All rights Reserved.  U.S. Government
c	Sponsorship under NASA Contract NAS7-918 is
c	acknowledged.
c
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

	program reduce

	implicit none

	character*40	file
	character*10	cbyte

	byte		b(10,1024,4)
	byte		b2(10240,4)
	byte		bb(10240)
	byte		a(10)
	byte		oldhead(10240)

	equivalence	(b, b2)

	real		xxx(-50:50,-127:127)
	real		expscale

	common		b,xxx

	logical		exists

	integer		ichan,ochan
	integer		inreclen, outreclen
	integer		i,j,k,l,jj
	integer		iheadlines, ivarlines
	integer		iw, ih, isub
	integer		ix, iy
	integer		inoff, outoff
	integer		ibytesoldhead
	integer		ibytesdata
	integer		ireclen
	integer		icount

	common /header/	xxreclen,		! bytes per record
     +				xxhead,		! number of header lines
     +				xxsamp,		! number of samples per record
     +				xxline,		! number of lines in image
     +				xxbytesamp,		! bytes per sample
     +				xxversion,		! processor version number
     +   			xxdatatype,		! data type
     +				xxprojection,	! slant/ground range proj.
     +				xxrspace,		! range pixel spacing
     +				xxazspace,		! azimuth pixel spacing
     +				xxbytesoldhead,	! byte offset to old header
     +				xxbytesuserhead,	! byte offset to user header
     +				xxbytesdata		! byte offset to data

	integer*4 	xxreclen
	integer*4	xxhead
	integer*4	xxsamp
	integer*4	xxline
	integer*4	xxbytesamp
	integer*4	xxbytesoldhead
	integer*4 	xxbytesuserhead
	integer*4	xxbytesdata

	real*4    		xxversion
	real*4		xxrspace
	real*4		xxazspace

	character*20 	xxprojection
	character*20	xxdatatype

c	WELCOME

	type *
	type *,'             <<< Reduce >>>'
	type *

C	GET INPUT DATA FILE NAME

100	type *,'Enter input data file name --> '
	accept '(a)',file
	type *

C	SEE IF INPUT DATA FILE EXISTS

	inquire (file=file,exist=exists)
	if (.not.exists) then
	   type *, '*** ERROR - input file does not exist ***'
	   type *
	   stop
	end if

C	GET THE INPUT FILE RECORD LENGTH

	type *,'Enter input file physical record length (bytes) --> '
	accept *, inreclen
	type *

C	OPEN INPUT DATA FILE

	ichan = 40
	open (ichan, file=file, status='old', readonly,
     +     form='unformatted', access='direct', recl=inreclen/4)

C	GET THE INPUT FILE VARIABLE HEADER

	call readheadshort (ichan, inreclen)
	ibytesoldhead = xxbytesoldhead
	ibytesdata = xxbytesdata
	ireclen = xxreclen
	type *,'Samples in input file: ',xxsamp
	type *,'Lines in input file:   ',xxline
	type *

C	GET OUTPUT FILE SPECIFICATIONS

200	type *,'Enter width and height of output data set'
	type *,'(width must be multiple of 256) --> '
	accept *,iw,ih
	type *
	if (iw.lt.256.or.mod(iw,256).ne.0.or.iw.gt.xxsamp) then
	   type *,'*** ERROR - Width must be a multiple of 256 ***'
	   type *
	   goto 200
	end if
	if (ih.lt.1.or.ih.gt.xxline) then
	   type *,' *** ERROR - Height must be between 1 and ',
     +		xxline,' ***'
	   type *
	   goto 200
	end if

400	type *,'Enter amount of averaging (1..4)'
     	type *,'(e.g. N = average every NxN pixels) --> '
	accept *,isub
	type *
	if (isub.lt.1) then
	   type *,'** INPUT ERROR ** Averaging must be >= 1'
	   type *
	   goto 400
	end if
	if (isub.gt.4) then
	   type *,'** INPUT ERROR ** Averaging must be <= 4'
	   type *
	   goto 400
	end if
	if (isub*iw.gt.xxsamp) then
	   type *,' ** INPUT ERROR ** Width times averaging is > ',
     +		xxsamp
	   goto 200
	end if
	if (isub*ih.gt.xxline) then
	   type *,' ** INPUT ERROR ** Height times averaging is > ',
     +		xxline
	   goto 200
	end if

300	type *,'Enter x,y of upper left corner'
        type *,'((0,0)=uppermost left pixel) --> '
	accept *,ix,iy
	type *
	if (ix.lt.0.or.iy.lt.0)
     +	   type *,'** INPUT ERROR ** X and y must be >= 0'
	if (ix.lt.0.or.iy.lt.0) goto 300
	if (ix.gt.xxsamp-iw*isub) then
           type *,'** INPUT ERROR ** X is too large for the requested'
	   type *,'                  image'
	   type *
	   goto 300
	end if
	if (iy.gt.xxline-ih*isub) then
           type *,'** INPUT ERROR ** Y is too large for the requested'
	   type *,'                  image'
	   type *
	   goto 300
	end if

C	GET OUTPUT FILE NAME

500	continue
	type *,'Enter output file name --> '
	accept '(a)', file
	type *

C	GET THE OUTPUT FILE RECORD LENGTH

	type *,'Enter output file physical record length (bytes) --> '
	accept *, outreclen
	type *

C	OPEN NEW FILE

	ochan = 41
	open (ochan, file=file, form='unformatted',
     +     status='unknown', access='direct', recl=outreclen/4)

C	STORE VARIABLE FORMAT HEADER

	iheadlines = 1023/(iw*10)+8191/(iw*10)+2
	ivarlines  = 1023/(iw*10)+1

	xxreclen = iw * 10
	xxhead = iheadlines
	xxsamp = iw
	xxline = ih
	xxbytesamp = 10
	xxbytesoldhead = ivarlines*iw*10
	xxbytesuserhead = 0		! ASSUME NO USER HEADER!!!!
	xxbytesdata = iheadlines*iw*10

	call writehead (ochan,ix,iy,isub,outreclen)
	type *

C	STORE OLD HEADER

	type *,'Storing old header...'
	inoff = (ibytesoldhead-1) /inreclen+1
	outoff= (xxbytesoldhead-1)/outreclen+1
	do i = 1, 8191/inreclen+1
	   read  (ichan, rec=i+inoff) 
     +        (oldhead(j),j=(i-1)*inreclen+1,i*inreclen)
	end do
	do i = 1, 8191/outreclen+1
	   write (ochan, rec=i+outoff) 
     +        (oldhead(j),j=(i-1)*outreclen+1,i*outreclen)
	end do
	type *

C	STORE DATA

	if (isub.ne.1) then
	   do i = -50,50
	      expscale=2.**i
	      do j = -127,127
		 xxx(i,j)=(j/254.+1.5)*expscale
	      end do
	   end do
	end if

	type *,'Writing file...'
	type *

	inoff  = (ibytesdata-1) /inreclen+1+iy*((ireclen-1)/inreclen+1)
	outoff = (xxbytesdata-1)/outreclen+1

	do i = iy,iy+ih*isub-1,isub
	   if (mod(i,10).eq.0) type *, 'line', i
	   do j = 1,isub
	      do k = 1, (ireclen-1)/inreclen+1
	         read (ichan, rec=k+inoff) 
     +              (b2(l,j),l=(k-1)*inreclen+1,k*inreclen)
	      end do
	      inoff = inoff + (ireclen-1)/inreclen+1
	   end do
	   icount = 0
	   if (isub.eq.1) then
	      do j = ix,ix+iw-1
	         do jj = 1,10
		    icount = icount + 1
		    bb(icount) = b(jj,j+1,1)
	         end do
	      end do
	   else
	      do j = ix,ix+iw*isub-1,isub
		 call average (j,a,isub)
		 do jj = 1,10
		    icount = icount + 1
		    bb(icount) = a(jj)
		 end do
	      end do
	   end if
	   do k = 1, (xxreclen-1)/outreclen+1
	      write (ochan, rec=k+outoff)
     +           (bb(l),l=(k-1)*outreclen+1,k*outreclen)
	   end do  
	   outoff = outoff + (xxreclen-1)/outreclen+1
	end do

	type *,'...done'
	type *

	end

cccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c	AVERAGE
c
c	This subroutine uncompresses the 10 bytes
c	stored in the common array b to form a Stokes
c	matrix.  The parameter isub indicates how much
c	averaging is to be done.  The input parameter
c	ix indicates the starting pixel for averaging
c	(the first pixel = 0).  The array a contains the
c	compressed results.
c
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

	subroutine average (ix,a,isub)

	implicit none

	integer		i,j,ii,jj
	integer		ix, isub
	integer		iexp, imant
	integer		i12, i33, i44, i13, i14, i23,  i24, i34
	byte			a(10)
	byte			b(10,1024,4)
	real			xxx(-50:50,-127:127)
	common		b,xxx

	real		p(4,4),sump(4,4),ph11
	real		alog2
	real		scale, sca
	real		exp

	alog2 = alog10(2.0)

c	CLEAR STOKES MATRIX

	do i = 1,4
	   do j = 1,4
	      sump(i,j) = 0
	   end do
	end do

c	DECOMPRESS AND ACCUMULATE

	do i = ix,ix+isub-1
	   do j = 1,isub	
	      call pmatrix(b(1,i+1,j),p)
	      do ii=1,4
		 do jj=1,4
		    sump(ii,jj) = sump(ii,jj)+p(ii,jj)
		 end do
	      end do
	   end do
	end do

c	AVERAGE

	do i = 1,4
	   do j = 1,4
	      sump(i,j) = sump(i,j)/(isub*isub)
	   end do
	end do

c	RECOMPRESS

	do i = 1, 10
	   a(i) = 0
	end do

	scale = sump(1,1)

	if (scale.gt.0.0) then

	   exp = alog10(scale)/alog2
	   iexp = exp
	   if (exp.lt.0) iexp = exp-1
	   imant = nint((scale*2.0**(-iexp)-1.5)*254.0)

	   sca = xxx(iexp,imant)/127.

	   if (sca.gt.0) then

	      ph11 = xxx(iexp,imant)
	      sump(1,3) = sign(sqrt(abs(sump(1,3))/ph11),sump(1,3))
	      sump(1,4) = sign(sqrt(abs(sump(1,4))/ph11),sump(1,4))
	      sump(2,3) = sign(sqrt(abs(sump(2,3))/ph11),sump(2,3))
	      sump(2,4) = sign(sqrt(abs(sump(2,4))/ph11),sump(2,4))
		 
	      i12 = nint(sump(1,2)/sca)
	      i33 = nint(sump(3,3)/sca)
	      i44 = nint(sump(4,4)/sca)
	      i13 = nint(sump(1,3)*127.)
	      i14 = nint(sump(1,4)*127.)
	      i23 = nint(sump(2,3)*127.)
	      i24 = nint(sump(2,4)*127.)
	      i34 = nint(sump(3,4)/sca)

	      a(1) = iexp
	      a(2) = imant
	      a(3) = i12
	      a(4) = i13
	      a(5) = i14
	      a(6) = i23
	      a(7) = i24
	      a(8) = i33
	      a(9) = i34
	      a(10) = i44

	   end if

        end if

	end

ccccccccccccccccccccccccccccccccccccccccc
c
c	PMATRIX
c
c	This subroutine uncompresses the
c	10 bytes to form the 4x4 real
c	Stokes matrix.
c
ccccccccccccccccccccccccccccccccccccccccc

	subroutine pmatrix (data,p)

	implicit none

	real 		p(4,4)
	real		sc, r
	byte 		data(10)

	byte		b(10,1024,4)
	real		xxx(-50:50,-127:127)
	common	b,xxx

	sc = xxx(data(1),data(2))/127.
	p(1,1) = 127*sc
	p(1,2) = data(3)*sc
	r = data(4)
	p(1,3) = sign(r*r,r)*sc/127.
	r = data(5)
	p(1,4) = sign(r*r,r)*sc/127.
	p(2,1) = p(1,2)
	r = data(6)
	p(2,3) = sign(r*r,r)*sc/127.
	r = data(7)
	p(2,4) = sign(r*r,r)*sc/127.
	p(3,1) = p(1,3)
	p(3,2) = p(2,3)
	p(3,3) = data(8)*sc
	p(3,4) = data(9)*sc
	p(4,1) = p(1,4)
	p(4,2) = p(2,4)
	p(4,3) = p(3,4)
	p(4,4) = data(10)*sc
	p(2,2) = p(1,1)-p(3,3)-p(4,4)

	return
	end

ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c  READHEADSHORT -- 
c 	This subroutine decodes the variable data header used
c	by JPL Aircraft data output products as described
c	below and saves the results in a common block.
c
c  Version 1.1  
c  by Howard Zebker, Lynne Norikane
c  14-AUG-89
c
c  This subroutine should be used to decode the variable data header
c  which exists at the beginning of each JPL Aircraft data output
c  product.  The header exists at the beginning of the file and is
c  composed of 20 50-byte ASCII fields.  The format of each field is as
c  follows:
c
c     Byte 1                                            Byte 50
c     DESCRIPTIVE TEXT  -- blanks (ascii 32) -- NUMERICAL VALUE
c
c  The descriptive text is left justified, and the numerical values are
c  right justified.  Intermediate characters are assumed to be blanks.
c
c  The fields contained in the header are as follows:
c
c	field	contents
c	-----   --------
c	1  	RECORD LENGTH IN BYTES =                   XXXXXXXX
c	2	NUMBER OF HEADER RECORDS =                 XXXXXXXX
c	3	NUMBER OF SAMPLES PER RECORD =             XXXXXXXX
c	4	NUMBER OF LINES IN IMAGE =                 XXXXXXXX
c	5	NUMBER OF BYTES PER SAMPLE =               XXXXXXXX
c	6	JPL AIRCRAFT SAR PROCESSOR VERSION            XX.XX
c	7	DATA TYPE =                       CCCCCCCCCCCCCCCCC
c	8	RANGE PROJECTION =                           CCCCCC
c	9	RANGE PIXEL SPACING (METERS) =            XXXX.XXXX
c	10	AZIMUTH PIXEL SPACING (METERS) =          XXXX.XXXX
c	11	BYTE OFFSET OF OLD HEADER =                XXXXXXXX
c	12	BYTE OFFSET OF USER HEADER =               XXXXXXXX
c	13	BYTE OFFSET OF FIRST DATA RECORD =         XXXXXXXX
c	14-20   TBD
c
c  where 'X's are replaced by numerical values and 'C's are replaced by
c  character strings.
c
c  This implementation returns all of the header information in the
c  common block. 
c
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

	subroutine readheadshort (ichan, reclen)

	implicit none

	common /header/	ireclen,	! bytes per record
     +				nhead,	! number of header lines
     +				nsamp,	! number of samples per record
     +				nline,	! number of lines in image
     +				nbytesamp,	! bytes per sample
     +				version,	! processor version number
     +   			datatype,	! data type
     +				projection,	! slant/ground range projection
     +				rspace,	! range pixel spacing
     +				azspace,	! azimuth pixel spacing
     +				ibytesoldhead,	! byte offset to old header
     +				ibytesuserhead,	! byte offset to user header
     +				ibytesdata	! byte offset to data

	integer*4	ireclen
	integer*4	nhead
	integer*4	nsamp
	integer*4	nline
	integer*4	nbytesamp
	integer*4	ibytesoldhead
	integer*4 	ibytesuserhead
	integer*4	ibytesdata	
	integer	reclen
	integer	i,j
	integer	ichan

	real*4    	version
	real*4	rspace
	real*4	azspace

	character*20 	projection
	character*20	datatype
	character*20	tt

	byte		head(10240)
	byte		t(25)

	equivalence (t,tt)

c  READ HEADER (1024 BYTES)

	do i = 1, 1023/reclen+1
	   read (ichan,rec=i) (head(j),j=(i-1)*reclen+1,i*reclen)
	end do

c  STRIP INTEGER VALUES FIRST

	decode(8,'(i8)',head(1*50-7))ireclen
	decode(8,'(i8)',head(2*50-7))nhead
	decode(8,'(i8)',head(3*50-7))nsamp
	decode(8,'(i8)',head(4*50-7))nline
	decode(8,'(i8)',head(5*50-7))nbytesamp

	decode(8,'(i8)',head(11*50-7))ibytesoldhead
	decode(8,'(i8)',head(12*50-7))ibytesuserhead
	decode(8,'(i8)',head(13*50-7))ibytesdata

c  STRIP REAL VALUES

	decode(8,'(f9.0)',head(6*50-8))version
	decode(8,'(f9.0)',head(9*50-8))rspace
	decode(8,'(f9.0)',head(10*50-8))azspace

c  STRIP CHARACTER VALUES

	do i=1,20
	   t(i)=head(8*50-20+i)
	end do
	projection=tt

	do i=1,20
	   t(i)=head(7*50-20+i)
	end do
	datatype=tt

	return

	end

cccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c  WRITEHEAD - 
c	This subroutine writes the variable data header used
c	by JPL Aircraft data output products.  It uses the
c	values stored in the variables in the common block.
c	It also adds the x,y offset and amount
c	of averaging to the header.
c
c  < see comments from READHEADSHORT >
c
c  THIS SUBROUTINE DOES NOT STORE THE OLD HEADER!
c
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

	subroutine writehead (outchan,iulx,iuly,iavg, reclen)

	implicit none

	common /header/	ireclen,	! bytes per record
     +			nhead,		! number of header lines
     +			nsamp,		! number of samples per record
     +			nline,		! number of lines in image
     +			nbytesamp,		! bytes per sample
     +			version,		! processor version number
     +			datatype,		! data type
     +			projection,		! slant/ground range projection
     +			rspace,		! range pixel spacing
     +			azspace,		! azimuth pixel spacing
     +			ibytesoldhead,	! byte offset to old header
     +			ibytesuserhead,	! byte offset to user header
     +			ibytesdata		! byte offset to data

	integer*4 	ireclen
	integer*4	nhead
	integer*4	nsamp
	integer*4	nline
	integer*4	nbytesamp
	integer*4	ibytesoldhead
	integer*4 	ibytesuserhead
	integer*4	ibytesdata

	integer		outchan
	integer		reclen
	integer		i,j,k
	integer		iulx, iuly, iavg

	real*4		version
	real*4		rspace
	real*4		azspace

	character*20 	projection
	character*20	datatype

	character*50	header(16)
	character*10	string
	character*20	string20

	byte		bheader(50,16)
	byte		oneline(10240)
	byte		bstring(10),bstring20(20)

	equivalence	(header,bheader),(string,bstring),(string20,bstring20)

c	CREATE HEADER

	type *,'Writing variable header...'

	header(1) = 'RECORD LENGTH IN BYTES =                          '
	header(2) = 'NUMBER OF HEADER RECORDS =                        '
	header(3) = 'NUMBER OF SAMPLES PER RECORD =                    '
	header(4) = 'NUMBER OF LINES IN IMAGE =                        '
	header(5) = 'NUMBER OF BYTES PER SAMPLE =                      '
	header(6) = 'JPL AIRCRAFT SAR PROCESSOR VERSION                '
	header(7) = 'DATA TYPE =                                       '
	header(8) = 'RANGE PROJECTION =                                '
	header(9) = 'RANGE PIXEL SPACING (METERS) =                    '
	header(10) = 'AZIMUTH PIXEL SPACING (METERS) =                  '
	header(11) = 'BYTE OFFSET OF OLD HEADER =                       '
	header(12) = 'BYTE OFFSET OF USER HEADER =                      '
	header(13) = 'BYTE OFFSET OF FIRST DATA RECORD =                '
	header(14) = 'UPPER LEFT CORNER X (0-1023) =                    '
	header(15) = 'UPPER LEFT CORNER Y (0-1023) =                    '
	header(16) = 'AVERAGING (1,2,4) =                               '

c	SAVE RECORD LENGTH IN BYTES

	encode (10,'(i10)',string) ireclen
	do i = 1,8
	   bheader(i+42,1) = bstring(i+2)
	end do

c	SAVE NUMBER OF HEADER LINES

	encode (10,'(i10)',string) nhead
	do i = 1,8
	   bheader(i+42,2) = bstring(i+2)
	end do

c	SAVE NUMBER OF SAMPLES

	encode (10,'(i10)',string) nsamp
	do i = 1,8
	   bheader(i+42,3) = bstring(i+2)
	end do

c	SAVE NUMBER OF LINES

	encode (10,'(i10)',string) nline
	do i = 1,8
	   bheader(i+42,4) = bstring(i+2)
	end do

c	SAVE NUMBER OF BYTES PER SAMPLE

	encode (10,'(i10)',string) nbytesamp
	do i = 1,8
	   bheader(i+42,5) = bstring(i+2)
	end do

c	SAVE SAR PROCESSOR VERSION NUMBER

	encode (10,'(f10.4)',string) version
	do i = 1,9
	   bheader(i+41,6) = bstring(i+1)
	end do

c	SAVE DATA TYPE

	string20(1:20) = datatype(1:20)
	do i = 1,20
	   bheader(i+30,7) = bstring20(i)
	end do

c	SAVE PROJECTION

	string20(1:20) = projection(1:20)
	do i = 1,20
	   bheader(i+30,8) = bstring20(i)
	end do

c	SAVE RANGE PIXEL SPACING

	encode (10,'(f10.4)',string) rspace
	do i = 1,9
	   bheader(i+41,9) = bstring(i+1)
	end do

c	SAVE AZIMUTH PIXEL SPACING

	encode (10,'(f10.4)',string) azspace
	do i = 1,9
	   bheader(i+41,10) = bstring(i+1)
	end do

c	SAVE BYTE OFFSET TO OLD HEADER

	encode (10,'(i10)',string) ibytesoldhead
	do i = 1,8
	   bheader(i+42,11) = bstring(i+2)
	end do

c	SAVE BYTE OFFSET TO USER HEADER

	encode (10,'(i10)',string) ibytesuserhead
	do i = 1,8
	   bheader(i+42,12) = bstring(i+2)
	end do

c	SAVE BYTE OFFSET TO DATA

	encode (10,'(i10)',string) ibytesdata
	do i = 1,8
	   bheader(i+42,13) = bstring(i+2)
	end do

c	SAVE UPPER LEFT CORNER X

	encode (10,'(i10)',string) iulx
	do i = 1,8
	   bheader(i+42,14) = bstring(i+2)
	end do

c	SAVE UPPER LEFT CORNER Y

	encode (10,'(i10)',string) iuly
	do i = 1,8
	   bheader(i+42,15) = bstring(i+2)
	end do

c	SAVE AVERAGING

	encode (10,'(i10)',string) iavg
	do i = 1,8
	   bheader(i+42,16) = bstring(i+2)
	end do

c	WRITE HEADER TO FILE

	do i = 1,1024
	   oneline(i) = 32
	end do

	k = 1
	do i = 1,16
	   do j = 1,50
	      oneline(k) = bheader(j,i)
	      k = k + 1
	   end do
	end do

	do i = 1, 1023/reclen+1
	   write (outchan, rec=i) (oneline(j),j=(i-1)*reclen+1,i*reclen)
	end do

	return

	end

	

Appendix C: Variable

Format Header



The variable format header appears at the beginning of compressed Stokes matrix radar data files. It contains twenty 50-character fields:

             Column numbers:
      Field  12345678901234567890123456789012345678901234567890

        1    RECORD LENGTH IN BYTES =                  NNNNNNNN
        2    NUMBER OF HEADER RECORDS =                NNNNNNNN
        3    NUMBER OF SAMPLES PER RECORD =            NNNNNNNN
        4    NUMBER OF LINES IN IMAGE =                NNNNNNNN
        5    NUMBER OF BYTES PER SAMPLE =              NNNNNNNN
        6    JPL AIRCRAFT SAR PROCESSOR VERSION       XXXX.XXXX
        7    DATA TYPE =                             CCCCCCCCCC
        8    RANGE PROJECTION =                          CCCCCC
        9    RANGE PIXEL SPACING (METERS) =           XXXX.XXXX
        10   AZIMUTH PIXEL SPACING (METERS) =         XXXX.XXXX
        11   BYTE OFFSET OF OLD HEADER =               NNNNNNNN
        12   BYTE OFFSET OF USER HEADER =              NNNNNNNN
        13   BYTE OFFSET OF FIRST DATA RECORD =        NNNNNNNN
        14   UPPER LEFT CORNER X (0-1023) =            NNNNNNNN
        15   UPPER LEFT CORNER Y (0-1023) =            NNNNNNNN
        16   AVERAGING (1,2,4) =                       NNNNNNNN
        17   (unused)
        18   (unused)
        19   (unused)
        20   (unused)

where 'NNNNNNNN' represents a right-justified integer value, 'XXXX.XXXX' represents a right-justified real number, and 'CCCCCCCC' represents a character string.

The
record length
is the width of the file in bytes. It can also be thought of as the number of bytes per line. For compressed Stokes matrix data, this number should be 10 times the number of samples per record.

The
number of header records
is the number of records used to store the variable format header, the "old" header, and the user header. If a header is longer than one record, it is assumed to wrap-around (i.e. continue from the end of one line to the beginning of the next).

The "old" header is composed of approximately 160 50-character fields and contains information recorded during the acquisition of the data and information added during correlation and possibly calibration. In versions of the SAR correlator prior to 1990, this is the only header saved with each data set (it is saved in the 1025th line of the file). With the addition of the variable format header, this header became the "old" header.

The
number of samples
per record is the number of pixels per record. The record length and the number of samples per record may differ if more than one byte is stored per pixel as is the case with compressed Stokes matrix data.

The
number of lines
in the image is exactly that.

The
number of bytes per sample
is 10 for compressed Stokes matrix data. The number of bytes per sample times the number of samples per record should be equal to the number of bytes per record.

The
SAR processor version number
can be used to identify which processor was used to convert the raw polarimetric data to compressed Stokes matrix data.

The
data type
is an ASCII description of what is contained in the file. Compressed Stokes matrix data usually says "COMPRESSED".

The
range projection
is either "SLANT" or "GROUND". A slant range projection indicates that the distance from the aircraft to the image line on the ground increments the same amount between each line. A ground range projection indicates that the distance from the aircraft's position projected on the ground to the image line on the ground increments the same amount between each line.

The
range pixel spacing
is the amount of increment in meters between image lines on the ground (see paragraph above).

The
azimuth pixel spacing
is the amount of increment in meters between horizontal pixels.

The
byte offset of the old header
is the number of bytes which precede the first byte in the "old" header. For example, if the "old" header starts at byte number 1025 and the first byte of the file is byte 1, then the byte offset would be 1024. If the "old" header does not exist, then the offset should be 0.

The
byte offset of the user header
is the number of bytes which precede the first byte of the user header. This value is usually 0.

The
byte offset of the data
is the number of bytes which precede the first byte of data. It is also usually the same as the number of header lines times the number of bytes per record.

The
upper left corner x
and
upper left corner y
are the coordinates of the upper left corner of this image within the original image produced by the SAR processor. For example, suppose the original image contained 1024 samples by 750 lines. Generally, it is easier to work with smaller data sets on the Macintosh due to speed and memory limitations so you choose to save a 256 x 256 subset of the image from the center of the original image. The upper left corner coordinate should then be (1024/2 - 256/2, 750/2 - 256/2) or (384,247). If you chose to average the entire 1024 x 750 data set down to 256 x 187, then the upper left corner coordinate should be (0,0).

The
amount of averaging
should be 1, 2, or 4. A value of 1 indicates that no averaging has been done and a value of 4 indicates that every set of 4 x 4 pixels in the original data set was averaged down to one pixel in the Macintosh data set.

Appendix D: The "Old" Header




The "old" header is generally composed of up to 160 50-byte text fields. Each field starts with a description of a parameter and a value. The value may occur anywhere after the description within the 50 byte field. Non-text characters may be spaces or the null character (ASCII 0). Fields are NOT terminated with a carriage return or line feed.

The following is part of an "old" header:

Field   1:  CORRELATION DATE: 21-MAR-92
Field   2:  NEAR RANGE (METERS):    8963.794
Field   3:  SLANT RANGE PIXEL (M.):  6.662
Field   4:  AZIMUTH PIXEL (M.):      12.16
Field   5:  INCID.ANG.(NEAR RANGE)(DEG.):    23.00957
Field   6:  MULTIPOLARIZATION L-BAND
Field   7:  POLARIZATION = Quad Pol Mode
Field   8:  NUMBER OF ERRORS DETECTED =     0
Field   9:  FIRST FRAME COUNT =         1703204
Field  10:  DISTANCE TO GO         32.0 NAUTICAL MILES
Field  11:  TIME TO GO             4.7 MIN
Field  12:  CROSS TRACK DEV.        0.1 FEET
Field  13:  DESIRED TRACK ANG.   115.3 DEGREES
Field  14:  TRACK ANG. ERROR       0.2 DEGREES
Field  15:  DRIFT ANGLE          -8.1 DEGREES
Field  16:  ALIGN STATUS        34
Field  17:  LAT    52 DEG.18.2 MIN. N.
Field  18:  LONG   5  DEG.10.9 MIN. E.
Field  19:  GROUND SPEED         407 KNOTS
Field  20:  TRACK ANGLE         115.5 DEGREES
Field  21:  TRUE HEADING        123.5 DEGREES
Field  22:  WIND SPEED           83 KNOTS
Field  23:  WIND ANGLE          260 DEGREES
Field  24:  DAY OF YEAR:  166
Field  25:  TIME GMT:   9:38:44
Field  26:  RADAR ALTITUDE (M.):    8250
Field  27:  RADAR ALTITUDE      27069 FEET
Field  28:  AIRCRAFT PITCH        3.3 DEGREES
Field  29:  AIRCRAFT ROLL         -1.0 DEGREES
Field  30:  DIGITAL DELAY      87 MICROSECONDS
Field  31:  MONTH/DAY/YEAR     06/15/91
Field  32:  DIGITAL RUN NUMBER 0 / 0 / 0
Field  33:  DIGITAL REC. WINDOW  66 MICROSECONDS
Field  34:  ANTENNA =          Standard Modes
Field  35:  PRF FREQUENCY IS CONTROLLED BY: INS
Field  36:  TARGET LATITUDE    +52 17.8 DEGREES
Field  37:  TARGET LONGITUDE   +005 32.7 DEGREES
Field  38:  TARGET ELEVATION   0000 FEET
Field  39:  TARGET LOOK ANGLE  45 DEGREES
Field  40:  SCENE TITLE: Flevoland116-1

Unfortunately, the parameter names and parameter locations have never remained constant from year to year. Thus the easiest way to search for needed parameters is by searching the entire header for key strings. The following is a list of parameters used from the "old" header and the methods used to search for them:

frequency

The "old" header is searched for the string "BAND". If the string is found, the frequency band "L", "C", or "P" is assumed to be located 2 characters in front of "BAND" (as in "L-BAND").

near range

The "old" header is searched for the string "NEAR RANGE". The near range value is assumed to fall somewhere in the next 40 characters. The near range is assumed to be in meters.

altitude

The 132nd field is searched for the string "ALTITUDE (M". If this string is not found, then the entire "old" header is searched for the string "RADAR ALTITUDE (M". Failing that, the string "ALTITUDE (M" is used again, but applied to the entire "old" header. The altitude is assumed to be located somewhere in the 50 bytes including and following the key string and is assumed to be in meters.

general scale factor

The 133rd field is searched for the string "SCALE FACTOR". If not found, then the field is searched for the string "gen_sca". The general scale factor is assumed to be contained within the 50 bytes including and following the key string.

track angle

The "old" header is searched for the string "TRACK ANGLE". The track angle is assumed to be contained within the next 39 characters and is assumed to be in degrees.

drift angle

The "old" header is searched for the string "DRIFT ANGLE". The drift angle is assumed to be contained within the next 39 characters and is assumed to be in degrees.


Copyright (c) 1996 National Aeronautics and Space Administration


How do I Use the Sigma0 Program? Frequently Asked Questions