Retrieval of Precipitable Water Source Code Document

Procedures in this file are for the retrieval of precipitable water from AVHRR. They are:


Compilation: See the file README.C for instructions on compiling this file.

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <math.h>
#include "globals.h"
long call_precip_water_avhrr(short argc, void *argv[]);
float precip_water_avhrr(float tb4, float tb5, float scan);

/************************* CALL PRECIPITABLE WATER *************************/

long call_precip_water_avhrr(short argc, void *argv[])


This function loops through the input arrays and calls 'precip_water' (below) for each pixel. It is called from an IDL program with the following statement:

ERROR = call_external(objfln,'call_precip_water_avhrr',ncols,nrows,tb4,tb5,$ scanang,cmask,badpix,pw)

Input (as pointers to the specified type):

ncols, nrows : Dimensions of 'tsurf' and the arrays pointed to by 'array' [short integer]. While these arrays are 2D, they are treated here as 1D. If scalar values are passed in, both of these values must be 1. If a 1D array is passed in, then 'nrows' must be 1.

tb4,tb5: AVHRR channels 4 and 5 brightness temperatures (K) [float]

scanang: Sensor scan angle (degrees) [float]

cmask: Cloud mask array, cloudy=CLOUDY, clear=CLEAR ('globals.h') [char]

badpix: Valid pixels array, where invalid=TRUE ('globals.h') [char]


pw: Total precipitable water (cm) [float] If badpix=TRUE, MISSING values are returned. If the pixel is CLOUDY then the values that this variable has on input is unchanged.

Additional Variables (from globals.h):

TRUE, FALSE : true and false flags to be used for returning error condition

Called by: precip_water_avhrr (an IDL procedure)

Calls: precip_water_avhrr (the C function below)


/* parameters passed in from IDL */

short ncols, nrows;
char *cmask, *badpix;
float *tb4, *tb5, *scanang, *pw;

/* local parameters */

long i;
long ERROR; /* Error flag, returned to IDL */

/* Check that correct number of parameters was passed */

if (argc != 8) {
fprintf(stdout, "argc = %d\r\n",argc);
return ERROR;

/* Cast passed parameters to local vars */

ncols = *(short *) argv[0];
nrows = *(short *) argv[1];
tb4 = (float *) argv[2];
tb5 = (float *) argv[3];
scanang = (float *) argv[4];
cmask = (char *) argv[5];
badpix = (char *) argv[6];
pw = (float *) argv[7];

/* Loop through each pixel in the arrays. If it is a "bad" pixel, skip it and assign the fluxes a MISSING value.*/


for (i=0; i<nrows*ncols; i++) {
if (badpix[i] != (char) TRUE) {
pw[i] = precip_water_avhrr(tb4[i],tb5[i],scanang[i]);
if ( pw[i] > 5. ) pw[i] = 5. ;
if ( pw[i] < .5 ) pw[i] = .5 ;
if ( pw[i] == MISSING ) badpix[i] = 1 ;
pw[i] = MISSING;

return ERROR;

/**************************** PRECIPITABLE WATER ***************************/

float precip_water_avhrr(float tb4, float tb5, float scan)


Estimates the clear-sky total precipitable water from the split-window channels, based on a regression of Lowtran-modelled brightness temps and precipitable water from rawinsonde data. This procedure operates on scalar values only.


tb4,tb5 : Channels 4 and 5 brightness temperatures (K)

scan : Sensor scan angle (degrees)


pw: Total precipitable water (cm)

Called by: call_precip_water

Calls: None

Algorithm Summary:

The total precipitable water (cm) in the atmospheric vertical column is estimated using the split-window thermal channels. The relationship is:

PW = exp[b0 + b1(T4-T5) + b2(T5)] cos(theta)

where Ti is the brightness temperature of an AVHRR channel i and theta is the sensor scan angle. The coefficients b0, b1, and b2 were determined over a range of surface temperatures and water vapor amounts using AVHRR radiances modelled with LOWTRAN-7. Arctic rawinsonde data were employed. This procedure is for clear-sky pixels only. Initially converted to C from IDL by Todd Hutchinson, University of Colorado. Further modified by J. Key

float pw;
float tmp;

/* if the difference between tb4 and tb5 is too large, it can cause pw to be
too large and the program may core dump. Too eliminate this, set pw to
missing if tb4-tb5 too large. In the calculation of pw, the
division by 10 is necessary to convert mm to cm. */

if ((tmp < -3.)||(tmp > 10.)) pw = MISSING;
else {
tmp= -10.4974 + 0.751008*tmp + 0.0453005*tb5;
pw = exp(tmp) * cos(scan*DEGRAD) / 10.;

return pw;