The function c_calcoef, and its support functions ccupdt and ccprim, will be modified to eliminate channel 4 and 5 coefficient changes due to a 3a/3b sensor change. This will entail a major redesign of the code. Because of the scope of this redesign, the errors in PRT usage addressed by CR 6321 will be corrected. And, at the same time, the NOAA techniques for PRT usage and filtering of PRT, space and blackbody counts will be implemented as closely as possible.
"For the average, use PRTs from the 5 scanlines you're interested in
,
As you said, the 50 Space counts for the average come from the 5
Jerry
The AVRHH calibration uses the concept of a calibration block and
Dave,
The 2nd paragraph in this email is the formal statement of which
PRT
counts are used. Another way of saying it is:
plus PRTs from the 25 scanlines BEFORE these 5 and PRTs from the 25
scanlines AFTER these 5."
scanlines you're interested in (10 counts per scanline) and the same
goes for the Internal Calibration Target blackbody counts. These
50-count data sets are also quality controlled by a gross limits check
and a 2-sigma filter.
subblock. A calibration block is composed of the data from 11
subblocks
each of which contains 5 scan lines. The calibration is always
performed
for the middle subblock. All the PRT data from the block -- that is
from
the 44 scans lines that actually contain PRT data -- are converted to
temperature, then they are quality checked (a gross limits check and a
2-sigma filter) and the survivors are used to determine the radiance
of
the calibration target. The space and calibration counts from the
subblock being calibrated are quality checked and the survivors are
used
to compute the calibration coefficients. After the earth location is
performed and the 1b data is output, a new subblock is read in (the
oldest passes out of memory) and the process repeats.
The above statement mentions a 2-sigma filter. However, when applied to test data sets, a 2-sigma filter was not sufficient to remove all significant differences between NOAA and EDC coefficients. A 4-sigma filter did remove all significant differences. We are awaiting confirmation of the exact filter being used. Also there still remains a slight, unaccounted for bias in the coefficients. The EDC coefficient 0 is slightly higher than NOAA's and coefficient 1 is slightly lower. (See following table. Difference is calculated as NOAA_coefficient_value - EDC_coefficient_value)
Coefficient 0 Coefficient 1 Chan Range Difference Range Difference 4 180.3 to 180.7 -0.001541 -0.2066 to -0.2072 1.99E-06 5 197.2 to 197.6 -0.001545 -0.2107 to -0.2112 1.38E-06There is also a question about the number of PRT values that NOAA uses. The underlined passage above may mean they use all 132 PRT values from the 44 lines instead of a single value from each line.
Notes:
Algorithm:
FUNCTION: c_calcoef INPUT: current line master line minor frame buffer input file descriptor model structure INPUT/OUTPUT: coefficient structure calibration structure RETURNS: E_SUCC E_FAILbegin function if it is the first time the function is called then initialize the calibration structure -- call ccload_struct on error return E_FAIL for non-KLM satellites (TIROS-N to NOAA14) calculate numerator of beta function (phihat*deltanu) numerator of the exp function load the first 55 lines of PRT temperatures: loop line = 1,6,11,...,51, index = 0,4,8,...,40 call get_prt_temps with line and temperature[index] on error return E_FAIL endloop endif check for sensor switch -- call ccsconfig on error return E_FAIL if sensor has changed then modify calstruct to indicate change has occurred endif Don't automatically fall into this recalculation on a sensor change unless it's the normal time to recalculate. We don't want to disrupt the normal channel 4 and 5 coefficient flow. if it's time to recalculate (current line % calper == 0) then if (current line > 30) the sub-block is no longer in the middle of the block of PRT temperatures so read a new sub-block of PRT temps OR if (num_image_lines - current line > 30) there are sufficient PRT's to read in another sub-block then update the index into PRT temperature array: index+4 % 44 call get_prt_temps with current line number + 30; will return four PRT temperature values from 5 lines on error return E_FAIL endif otherwise keep the current set of PRT temperatures call a function to compute the mean of all 44 PRT temperatures; this will be a function to do some sort of filtering: gross limits, 2-sigma, previous trends or some such, and compute the simple mean of the remaining values call get_mean_counts with current line number; will return average space counts for three bands and average internal counts for three bands (possibly biased by sat num) on error return E_FAIL call cc_update which will return updated calibration coefficients if illumination correction is specified call ccillum_corr on error return E_FAIL If there had been a sensor switch and the normal recalculation code didn't occur take care of that here. This will update the channel 3B coefficients for the rest of this sub-block. The previous section will take over in the following sub-block aligning the thermal coefficient calculations to the original blocking. else if sensor switch then if this is a 3B to 3A switch no other changes are necessary since the visible coefficients are already loaded in the structure and, if specified, illumination correction applied. However, if it's a 3A to 3B switch, the thermal coefficients must be computed for 3B. For simplicity cc_update will calculate all three thermal coefficients therefore: call get_mean_counts with current line number and temporary arguments for the space and blackbody counts return E_FAIL on error copy channel 3 space and blackbody counts to actual variables call cc_update, will return updated calibration coefficients on error return E_FAIL endif endif return E_SUCC end function
Notes:
Algorithm:
FUNCTION: cc_update INPUT: calibration structure mean PRT temperature mean space counts mean blackbody counts numerator of beta function numerator of exp function INPUT/OUTPUT: coefficient structure RETURNS: nonebegin function if NOAA KLM-series then compute thermal coefficients - cctmp2rad3 else compute thermal coefficients - cctmp2rad endif check for zero coefficients if not all zero then copy updated coefficients to output coefficient parameter endif return end function
line 1 194 194 194 line 2 203 202 202 line 3 128 0 0 line 4 198 199 47 line 5 202 202 202The reference line is line 3 in the example, PRT count 1 is line 4, PRT count 3 is line 1, and so on. Also note the two 1-bit errors in line 3, value 128, and line 4, value 47. The median of three filter is used to reduce the effect of these errors. If, after the median filter is applied, one, and only one, reference line is found, set that line as the index. If more than one reference line is found, the lines are drop lines or very noisy and temperatures cannot be determined. Set the values to zero and return. Otherwise calculate the temperature for each PRT and return.
Notes:
Algorithm:
FUNCTION: get_prt_temps INPUT: calibration structure current line starting line file descriptor pointer to array of temperatures OUTPUT: four temperature values in array pointed to RETURNS: E_SUCC E_FAILbegin function if it's an archive image ( calstr->file_type == ARCIMAGE ) then move to starting line -- arcseek on error return E_FAIL endif read CALPER (5) lines lsread for LAS image, arcread for archive image on error return E_FAIL put median of three PRT values (minor frame 17, 18 and 19) into value array ! extract and save the time stamps for each line if it's an archive image then reposition to current line and reread it -- arcseek, arcread The reread of the current line is to put all input buffers back the way they were before the call to this routine on error return E_FAIL else rewind the image -- lsrew on error return E_FAIL endif try to determine the index by searching the PRT value array for a single value < PRTREFERENCE (current code has PRTREFERENCE = 10) if there is only one, set the zero PRT index to that index value ! if an index could not be determined then ! check for a 166 2/3 millisecond interval between all time stamps ! in the previous and current sequences. ! if the check was okay then ! set the index to the previous index ! endif ! endif if an index was determined then calculate the temperatures temperature formula: temp = a0 + a1x + a2x^2 + a3x^3 + a4x^4 implement as: loop prt = 0 to 4, i = index + 1 % 5 to index + 4 % 5 temp[prt] = aij[prt][4] loop j = 3 to 0 temp[prt] = (temp[prt] * value[prt]) + aij[prt][j] end j loop end prt, i loop else set temps to 0 endif ! if the index is valid then ! save current line time stamps and index for next call ! endif return E_SUCC end function
Notes:
Algorithm:
FUNCTION: get_mean_counts INPUT: calibration structure current line starting line file descriptor OUTPUT: mean_space_counts[3] mean_blackbody_counts[3] RETURNS: E_SUCC E_FAILbegin function if it's an archive image ( calstr->file_type == ARCIMAGE ) then move to starting line -- arcseek on error return E_FAIL endif read CALPER (5) lines lsread for LAS image, arcread for archive image on error return E_FAIL put space counts, minor frame 23 to 52, into space values array; 10 per line multiplexed as 3, 4, 5, total of 50 per band put blackbody counts, minor frame 53 to 102, into blackbody values array; 10 per line multiplexed as 1, 2, 3, 4, 5, total of 50 per band, only extract bands 3, 4, and 5 if it's an archive image then reposition to current line and reread it -- arcseek, arcread The reread of the current line is to put all input buffers back the way they were before the call to this routine on error return E_FAIL else rewind the image -- lsrew on error return E_FAIL endif Compute the mean space and blackbody values for each band, this will be a separate function that will do some sort of filtering: gross limits, 2-sigma, previous trends or some such, and compute the simple mean of the remaining values return E_SUCC end function
The 2- and 4-sigma filters were implemented in testing as:
compute x-bar, the simple mean of the data set: x-bar = 1/n * summation i=1 to n (xsubi) compute sigma: sigma = sqrt(1/(n-1) * summation i=1 to n( xsubi - x-bar )^2) and filter: if ( abs( x-bar - value ) < SIGMA_MULT*sigma ) use the value else throw value awayThe gross limits code in ccupdt keeps a running average of the space and blackbody counts and throws out any value that is not within 25 of this average. It tends to throw away too many values towards the end of the image so it needs to be changed to keep a windowed average, perhaps the last 500 values which equates to 50 lines worth. Other than that the filter works well. A similar technique could be applied to the PRT temperatures, although the median of three filter seems to work quite well for this without the additional overhead.