This program applies dark, flat-field, radiometric, and temperature corrections for each
framelet based on the band's filter number. There is also an optional mask to replace
special pixels in the calibrated image. In order to output in I/F units, the cube must
have spice data.
Corrections are applied in the following order: Dark, Flat-field, Radiometric, Special pixel mask, and Temperature.
Dark Correction:
If the DarkFile parameter is set, the given file(s) will be used for calibration. If DarkFile
is set to "Default" or not set at all, the dark files will be looked up based on the time and
temperature in the WAC being calibrated. The parameter,MiddleTemperatureFpa, is used for
temperature and StartTime for time. This program, lrowaccal, will attempt to find the 2 dark
files with closest time/temperature and interpolate/extrapolate from them. The method for
finding dark files is as follows:
- Create filename template based on WAC image offset and type (UV, BW, etc). Example: WAC_UV_Offset68_*C_*T_Dark.????.cub
- Look in $lro/calibration/wac_darks for matching files.
- Sort files on two factors:
- abs(dark temp - WAC temp)
- abs(dark time - WAC time)
-
Example:
WAC Temp = 23.33 and WAC Time = 314264519.932493
WAC_UV_Offset68_-10C_319412928T_Dark.0005.cub
WAC_UV_Offset68_-15C_319412928T_Dark.0005.cub
WAC_UV_Offset68_-20C_311632116T_Dark.0005.cub
WAC_UV_Offset68_-20C_319412928T_Dark.0005.cub
WAC_UV_Offset68_-25C_319412928T_Dark.0005.cub
WAC_UV_Offset68_-30C_311632116T_Dark.0005.cub
becomes
WAC_UV_Offset68_-25C_319412928T_Dark.0005.cub
WAC_UV_Offset68_-20C_311632116T_Dark.0005.cub
WAC_UV_Offset68_-20C_319412928T_Dark.0005.cub
WAC_UV_Offset68_-30C_311632116T_Dark.0005.cub
WAC_UV_Offset68_-15C_319412928T_Dark.0005.cub
WAC_UV_Offset68_-10C_319412928T_Dark.0005.cub
- Take the 2 closest temperatures (-25C and -20C in the example).
- Select the closest time for each temperature.
Example result:
WAC_UV_Offset68_-25C_319412928T_Dark.0005.cub
WAC_UV_Offset68_-20C_311632116T_Dark.0005.cub
-
If only one temperature is available, the 2 times that are closest to the WAC time will be
chosen. This will allow WACs to always be calibrated against something, instead of just
failing.
Example result:
WAC_UV_Offset68_-20C_311632116T_Dark.0005.cub
WAC_UV_Offset68_-20C_319412928T_Dark.0005.cub
Once the dark files are found, the correction is applied:
output[pixel] -= (dark1[pixel] - dark2[pixel])/(dark1Temp - dark2Temp)*(frameTemp-dark2Temp) + dark2[pixel]
where
dark1, dark2 = dark file cubes
dark1Temp, dark2Temp = temperature of dark1 file and dark2 file
frameTemp = (WAC EndTemperatureFpa - WAC BeginTemperatureFpa)/WAC NumFramelets * frame + WAC BeginTemperatureFpa
Flat-field Correction:
output[pixel] /= flatfield[pixel]
If FlatfieldFile is not set, flat-field cube is loaded from $lro/calibration/wac_flats/WAC_<wac mode>_Flatfield.????.cub
Radiometric Correction:
output[pixel] /= WAC ExposureDuration
if radiometricType == iof
output[pixel] *= solarDistance2 / iofResponsivity[band]
else
output[pixel] /= radianceResponsivity[band]
where
solarDistance is distance from the Moon to the Sun
If RadiometricFile is not set, radiometric responsivity is loaded from $lro/calibration/WAC_RadiometricResponsivity.????.pvl
Special Pixel Mask:
for each framelet in the output cube
if specialPixelMask[pixel] is special
outputFramelet[pixel] = specialPixelMask[pixel]
If SpecialPixelsFile is not set, special pixel mask is loaded from $lro/calibration/wac_masks/WAC_<wac mode>_<temp>C_SpecialPixels.????.cub. temp is closest temperature to WAC MiddleTemperatureFpa.
Temperature Correction:
for each framlet in the output cube
if output[pixel] is special- leave it alone
else preform the correction
Correction:
inputPixel
--------------------
a*(frameTemp) + b
Where:
'a' and 'b' are band dependent constants, read in from a file.
AND
frameTemp = (WAC EndTemperatureFpa - WAC BeginTemperatureFpa)/WAC NumFramelets * frame + WAC BeginTemperatureFpa
If TEMPRATUREFILE is not set, the constants are loaded from $lro/calibration/WAC_TempratureConstants.????.pvl
The DN level in an uncalibrated image is the sum of the true signal from the scene,
the bias, the dark current, and random noise in all 3 components. The random noise in
the true signal and dark current is called shot noise and the random noise in the bias
is called read noise. The true signal, bias, and dark current are defined as mean
values so that if the random noise were averaged down to insignificance by taking a
very large number of images and averaging them, the resulting image would be the true
scene, bias, and dark current with no systematic error. That implies the statistical
distribution of the random noise has an average of zero, and therefore the random noise
has both positive and negative values, except for the trivial case of zero random noise.
The calibration equation is:
reportedDN = ObservedDN - MeanBias - DarkCurrent
Where:
ObservedDN = TrueDN + E
E is a randomly sampled value from (mu, sigma^2) and mu=0
TrueDN is the signal that would be reported in an idealized case of an instrument with zero noise.
Let's look at the case of a calibrated image for which the true signal
is zero, a dark image. In calibration the mean bias and dark current are
subtracted. The random noise term is then randomly sampled from a known
distribution with a mean of zero. Since the distribution has a mean of
zero, values for the random noise can be positive or negative.
Therefore, the addition of random noise to a pixel with true signal near
zero can result in negative DN values.
Negative reported DNs are possible when E < -1 * TrueDN. These are
pixels in a very dark image that happen to have a strongly negative
random noise value.
Note: ObservedDN and TrueDN both must be greater than or equal to zero.
For ObservedDN, it's because the hardware is not able to report negative
DN values . For TrueDN, it's because radiance and reflectivity cannot be
negative. The dimmest target is one that is completely dark, and for
that target TrueDN = 0.
If run on a non-spiceinited cube, this program requires access to local mission-specific
SPICE kernels, in order to find the distance between the sun and the target body.
When run on a spiceinited cube, this can be determined using the camera model.
Using a spiceinited cube as input has the advantage of not requiring that local
mission-specific kernels be available. (See spiceinit web=true.)