! ! CRTM_Planck_Functions ! ! Module containing the sensor Planck function routines. ! ! ! CREATION HISTORY: ! Written by: Paul van Delst, CIMSS/SSEC 08-Aug-2001 ! paul.vandelst@ssec.wisc.edu ! MODULE CRTM_Planck_Functions ! ----------------- ! Environment setup ! ----------------- ! Module use statements USE Type_Kinds , ONLY: fp USE CRTM_Parameters, ONLY: ONE USE CRTM_SpcCoeff , ONLY: SC ! Disable all implicit typing IMPLICIT NONE ! ------------ ! Visibilities ! ------------ PRIVATE PUBLIC :: CRTM_Planck_Radiance PUBLIC :: CRTM_Planck_Radiance_TL PUBLIC :: CRTM_Planck_Radiance_AD PUBLIC :: CRTM_Planck_Temperature PUBLIC :: CRTM_Planck_Temperature_TL PUBLIC :: CRTM_Planck_Temperature_AD ! ---------- ! Parameters ! ---------- CHARACTER(*), PARAMETER :: MODULE_RCS_ID = & '$Id: CRTM_Planck_Functions.f90 99117 2017-11-27 18:37:14Z tong.zhu@noaa.gov $' CONTAINS !-------------------------------------------------------------------------------- ! ! NAME: ! CRTM_Planck_Radiance ! ! PURPOSE: ! Subroutine to calculate the instrument channel radiance. ! ! CALLING SEQUENCE: ! CALL CRTM_Planck_Radiance( SensorIndex , & ! Input ! ChannelIndex, & ! Input ! Temperature , & ! Input ! Radiance ) ! Output ! ! INPUT ARGUMENTS: ! SensorIndex: Sensor index id. This is a unique index associated ! with a (supported) sensor used to access the ! shared coefficient data for a particular sensor. ! See the ChannelIndex argument. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! ChannelIndex: Channel index id. This is a unique index associated ! with a (supported) sensor channel used to access the ! shared coefficient data for a particular sensor's ! channel. ! See the SensorIndex argument. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! Temperature: Temperature for which the Planck radiance is ! to be calculated. ! UNITS: Kelvin, K ! TYPE: REAL(fp) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! OUTPUT ARGUMENTS: ! Radiance: Channel Planck radiance. ! UNITS: mW/(m^2.sr.cm^-1) ! TYPE: REAL(fp) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(OUT) ! ! RESTRICTIONS: ! Spectral coefficients are obtained from the CRTM_SpcCoeff module ! so only radiances for those sensors which are included in the spectral ! coefficient data file can be calculated. ! ! PROCEDURE: ! First a polychromatic correction is applied to give an effective ! Temperature, ! ! T_eff = bc1 + ( bc2 * T ) ! ! The sensor radiance is then calculated using the effective temperature: ! ! pc1 ! R = ------------------------ ! EXP( pc2 / T_eff ) - 1 ! ! The bc1, bc2, pc1, and pc2 values are obtained from the ! CRTM_SpcCoeff module which is filled during the initialisation ! phase. ! !-------------------------------------------------------------------------------- SUBROUTINE CRTM_Planck_Radiance( n, l , & ! Input Temperature, & ! Input Radiance ) ! Output ! Arguments INTEGER, INTENT(IN) :: n ! SensorIndex INTEGER, INTENT(IN) :: l ! ChannelIndex REAL(fp), INTENT(IN) :: Temperature REAL(fp), INTENT(OUT) :: Radiance ! Local variables REAL(fp) :: Effective_Temperature ! Apply the polychromaticity correction ! to obtain an effective temperature Effective_Temperature = SC(n)%Band_C1(l) + ( SC(n)%Band_C2(l) * Temperature ) ! Calculate the Planck radiance Radiance = SC(n)%Planck_C1(l) / & ! ----------------------------------------------------------- ( EXP( SC(n)%Planck_C2(l) / Effective_Temperature ) - ONE ) END SUBROUTINE CRTM_Planck_Radiance !-------------------------------------------------------------------------------- ! ! NAME: ! CRTM_Planck_Radiance_TL ! ! PURPOSE: ! Subroutine to calculate the tangent-linear instrument channel radiance. ! ! CALLING SEQUENCE: ! CALL CRTM_Planck_Radiance_TL( SensorIndex , & ! Input ! ChannelIndex , & ! Input ! Temperature , & ! Input ! Temperature_TL, & ! Input ! Radiance_TL ) ! Output ! ! INPUT ARGUMENTS: ! SensorIndex: Sensor index id. This is a unique index associated ! with a (supported) sensor used to access the ! shared coefficient data for a particular sensor. ! See the ChannelIndex argument. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! ChannelIndex: Channel index id. This is a unique index associated ! with a (supported) sensor channel used to access the ! shared coefficient data for a particular sensor's ! channel. ! See the SensorIndex argument. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! Temperature: Temperature for which the tangent-linear Planck radiance ! is to be calculated. ! UNITS: Kelvin, K ! TYPE: REAL(fp) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! Temperature_TL: Tangent-linear temperature for which the tangent-linear ! Planck radiance is required. ! UNITS: Kelvin, K ! TYPE: REAL(fp) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! OUTPUT ARGUMENTS: ! Radiance_TL: Tangent-linear Planck radiance. ! UNITS: mW/(m^2.sr.cm^-1) ! TYPE: REAL(fp) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(OUT) ! ! RESTRICTIONS: ! Spectral coefficients are obtained from the CRTM_SpcCoeff module ! so only radiances for those sensors which are included in the spectral ! coefficient data file can be calculated. ! ! PROCEDURE: ! First a polychromatic correction is applied to give an effective ! temperature, ! ! T_eff = bc1 + ( bc2 . T ) ! ! The sensor tangent-linear radiance is then calculated by first computing ! the exponential term, ! ! exponential = EXP( pc2 / T_eff ) ! ! and then the actual operator, ! ! pc1 . pc2 . bc1 . exponential ! F = ------------------------------------ ! ( T_eff . ( exponential - 1 ) )^2 ! ! which is the derivate of the Planck equation wrt temperature. The ! tangent-linear radiance is then determined by, ! ! dR = F . dT ! ! where dT is the input tangent-linear temperature. ! ! The bc1, bc2, pc1, and pc2 values are obtained from the ! CRTM_SpcCoeff module which is filled during the initialisation ! phase. ! !-------------------------------------------------------------------------------- SUBROUTINE CRTM_Planck_Radiance_TL( n, l , & ! Input Temperature , & ! Input Temperature_TL, & ! Input Radiance_TL ) ! Output ! Arguments INTEGER, INTENT(IN) :: n ! SensorIndex INTEGER, INTENT(IN) :: l ! ChannelIndex REAL(fp), INTENT(IN) :: Temperature REAL(fp), INTENT(IN) :: Temperature_TL REAL(fp), INTENT(OUT) :: Radiance_TL ! Local variables REAL(fp) :: Effective_Temperature REAL(fp) :: Exponential REAL(fp) :: F ! Apply the polychromaticity correction Effective_Temperature = SC(n)%Band_C1(l) + ( SC(n)%Band_C2(l) * Temperature ) ! Calculate the Planck function operator ! ! The exponential term Exponential = EXP( SC(n)%Planck_C2(l) / Effective_Temperature ) ! The operator, call it F F = SC(n)%Planck_C1(l) * SC(n)%Planck_C2(l) * Exponential * SC(n)%Band_C2(l) / & ! ------------------------------------------------------------------------ ( Effective_Temperature * ( Exponential - ONE ) )**2 ! Calculate the tangent-linear radiance Radiance_TL = F * Temperature_TL END SUBROUTINE CRTM_Planck_Radiance_TL !-------------------------------------------------------------------------------- ! ! NAME: ! CRTM_Planck_Radiance_AD ! ! PURPOSE: ! Subroutine to calculate the adjoint instrument channel radiance. ! ! CALLING SEQUENCE: ! CALL CRTM_Planck_Radiance_AD( SensorIndex , & ! Input ! ChannelIndex , & ! Input ! Temperature , & ! Input ! Radiance_AD , & ! Input ! Temperature_AD ) ! In/Output ! ! INPUT ARGUMENTS: ! SensorIndex: Sensor index id. This is a unique index associated ! with a (supported) sensor used to access the ! shared coefficient data for a particular sensor. ! See the ChannelIndex argument. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! ChannelIndex: Channel index id. This is a unique index associated ! with a (supported) sensor channel used to access the ! shared coefficient data for a particular sensor's ! channel. ! See the SensorIndex argument. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! Temperature: Temperature for which the tangent-linear Planck radiance ! is to be calculated. ! UNITS: Kelvin ! TYPE: REAL(fp) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! Radiance_AD: Adjoint Planck radiance. ! UNITS: mW/(m2.sr.cm-1) ! TYPE: REAL(fp) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! OUTPUT ARGUMENTS: ! Temperature_AD: Adjoint Planck temperature ! UNITS: Kelvin ! TYPE: REAL(fp) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN OUT) ! ! SIDE EFFECTS: ! The input adjoint radiance argument, Radiance_AD, is NOT set to zero ! before returning to the calling routine. ! ! RESTRICTIONS: ! Spectral coefficients are obtained from the CRTM_SpcCoeff module ! so only radiances for those sensors which are included in the spectral ! coefficient data file can be calculated. ! ! PROCEDURE: ! First a polychromatic correction is applied to give an effective ! temperature, ! ! T_eff = bc1 + ( bc2 . T ) ! ! The sensor tangent-linear radiance is then calculated by first computing ! the exponential term, ! ! exponential = EXP( pc2 / T_eff ) ! ! and then the actual operator, ! ! pc1 . pc2 . bc1 . exponential ! F = ------------------------------------ ! ( T_eff . ( exponential - 1 ) )^2 ! ! which is the derivate of the Planck equation wrt temperature. The ! adjoint temperature is then determined from, ! ! T_AD = T_AD + ( F . R_AD ) ! ! where T_AD and R_AD on the LHS are the input adjoint temperature and ! radiance respectively. ! ! The bc1, bc2, pc1, and pc2 values are obtained from the ! CRTM_SpcCoeff module which is filled during the initialisation ! phase. ! !-------------------------------------------------------------------------------- SUBROUTINE CRTM_Planck_Radiance_AD( n, l , & ! Input Temperature , & ! Input Radiance_AD , & ! Input Temperature_AD ) ! In/Output ! Arguments INTEGER, INTENT(IN) :: n ! SensorIndex INTEGER, INTENT(IN) :: l ! ChannelIndex REAL(fp), INTENT(IN) :: Temperature REAL(fp), INTENT(IN) :: Radiance_AD REAL(fp), INTENT(IN OUT) :: Temperature_AD ! Local variables REAL(fp) :: Effective_Temperature REAL(fp) :: Exponential REAL(fp) :: F ! Apply the polychromaticity correction Effective_Temperature = SC(n)%Band_C1(l) + ( SC(n)%Band_C2(l) * Temperature ) ! Calculate the Planck function operator ! ! The exponential term Exponential = EXP( SC(n)%Planck_C2(l) / Effective_Temperature ) ! The operator, call it F F = SC(n)%Planck_C1(l) * SC(n)%Planck_C2(l) * Exponential * SC(n)%Band_C2(l) / & ! ------------------------------------------------------------------------ ( Effective_Temperature * ( Exponential - ONE ) )**2 ! Calculate the adjoint temperature Temperature_AD = Temperature_AD + ( F * Radiance_AD ) END SUBROUTINE CRTM_Planck_Radiance_AD !-------------------------------------------------------------------------------- ! ! NAME: ! CRTM_Planck_Temperature ! ! PURPOSE: ! Subroutine to calculate the instrument channel brightness temperature. ! ! CALLING SEQUENCE: ! CALL CRTM_Planck_Temperature( SensorIndex , & ! Input ! ChannelIndex, & ! Input ! Radiance , & ! Input ! Temperature ) ! Output ! ! INPUT ARGUMENTS: ! SensorIndex: Sensor index id. This is a unique index associated ! with a (supported) sensor used to access the ! shared coefficient data for a particular sensor. ! See the ChannelIndex argument. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! ChannelIndex: Channel index id. This is a unique index associated ! with a (supported) sensor channel used to access the ! shared coefficient data for a particular sensor's ! channel. ! See the SensorIndex argument. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! Channel: Channel index id. This is a unique index ! to a (supported) sensor channel. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! Radiance: Radiance for which the Planck temperature is desired. ! UNITS: mW/(m^2.sr.cm^-1) ! TYPE: REAL(fp) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! OUTPUT ARGUMENTS: ! Temperature: Planck temperature. ! UNITS: Kelvin, K ! TYPE: REAL(fp) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! RESTRICTIONS: ! Spectral coefficients are obtained from the CRTM_SpcCoeff module ! so only temperatures for those sensors which are included in the spectral ! coefficient data file can be calculated. ! ! PROCEDURE: ! First the effective temperature is calculated from the inverse Planck function, ! ! pc2 ! T_eff = ------------------ ! LOG( pc1/R + 1 ) ! ! The polychromatic correction is then removed to provide the brightness ! temperature, ! ! T_eff - bc1 ! T = ------------- ! bc2 ! ! The bc1, bc2, pc1, and pc2 values are obtained from the ! CRTM_SpcCoeff module which is filled during the initialisation ! phase. ! !-------------------------------------------------------------------------------- SUBROUTINE CRTM_Planck_Temperature( n, l , & ! Input Radiance , & ! Input Temperature ) ! Output ! Arguments INTEGER, INTENT(IN) :: n ! SensorIndex INTEGER, INTENT(IN) :: l ! ChannelIndex REAL(fp), INTENT(IN) :: Radiance REAL(fp), INTENT(OUT) :: Temperature ! Local variables REAL(fp) :: Effective_Temperature ! Calculate the effective temperature Effective_Temperature = SC(n)%Planck_C2(l) / & ! ---------------------------------------------- LOG( ( SC(n)%Planck_C1(l) / Radiance ) + ONE ) ! Apply the polychromatic correction to ! obtain the true temperature Temperature = ( Effective_Temperature - SC(n)%Band_C1(l) ) / & ! -------------------------------------------- SC(n)%Band_C2(l) END SUBROUTINE CRTM_Planck_Temperature !-------------------------------------------------------------------------------- ! ! NAME: ! CRTM_Planck_Temperature_TL ! ! PURPOSE: ! Subroutine to calculate the tangent-linear instrument channel ! brightness temperature. ! ! CALLING SEQUENCE: ! CALL CRTM_Planck_Temperature_TL( SensorIndex , & ! Input ! ChannelIndex , & ! Input ! Radiance , & ! Input ! Radiance_TL , & ! Input ! Temperature_TL ) ! Output ! ! INPUT ARGUMENTS: ! SensorIndex: Sensor index id. This is a unique index associated ! with a (supported) sensor used to access the ! shared coefficient data for a particular sensor. ! See the ChannelIndex argument. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! ChannelIndex: Channel index id. This is a unique index associated ! with a (supported) sensor channel used to access the ! shared coefficient data for a particular sensor's ! channel. ! See the SensorIndex argument. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! Radiance: Radiance at which the tangent-linear Planck temperature ! is desired. ! UNITS: mW/(m^2.sr.cm^-1) ! TYPE: REAL(fp) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! Radiance_TL: Tangent-linear radiance for which the tangent-linear ! Planck temperature is desired. ! UNITS: mW/(m^2.sr.cm^-1) ! TYPE: REAL(fp) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! OUTPUT ARGUMENTS: ! Temperature_TL: Tangent-linear Planck temperature. ! UNITS: Kelvin, K ! TYPE: REAL(fp) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! RESTRICTIONS: ! Spectral coefficients are obtained from the CRTM_SpcCoeff module ! so only temperatures for those sensors which are included in the spectral ! coefficient data file can be calculated. ! ! PROCEDURE: ! First the logarithm argument is calculated, ! ! a = pc1/R + 1 ! ! The inverse Planck function operator is then calculated, ! ! pc1 . pc2 ! F = ------------------------------ ! bc2 . a . ( R . LOG( a ) )^2 ! ! and the tangent-linear temperature is then given by, ! ! dT = F . dR ! ! The bc1, bc2, pc1, and pc2 values are obtained from the ! CRTM_SpcCoeff module which is filled during the initialisation ! phase. ! !-------------------------------------------------------------------------------- SUBROUTINE CRTM_Planck_Temperature_TL( n, l , & ! Input Radiance , & ! Input Radiance_TL , & ! Input Temperature_TL ) ! Output ! Arguments INTEGER, INTENT(IN) :: n ! SensorIndex INTEGER, INTENT(IN) :: l ! ChannelIndex REAL(fp), INTENT(IN) :: Radiance REAL(fp), INTENT(IN) :: Radiance_TL REAL(fp), INTENT(OUT) :: Temperature_TL ! Local variables REAL(fp) :: Argument REAL(fp) :: F ! Calculate the Planck function operator ! ! The logarithm argument Argument = ( SC(n)%Planck_C1(l) / Radiance ) + ONE ! The operator, call it F F = SC(n)%Planck_C1(l) * SC(n)%Planck_C2(l) / & ! ------------------------------------------------------------------- ( SC(n)%Band_C2(l) * Argument * ( Radiance * LOG( Argument ) )**2 ) ! Calculate the tangent-linear temperature Temperature_TL = F * Radiance_TL END SUBROUTINE CRTM_Planck_Temperature_TL !-------------------------------------------------------------------------------- ! ! NAME: ! CRTM_Planck_Temperature_AD ! ! PURPOSE: ! Subroutine to calculate the adjoint instrument channel ! brightness temperature. ! ! CALLING SEQUENCE: ! CALL CRTM_Planck_Temperature_AD( SensorIndex , & ! Input ! ChannelIndex , & ! Input ! Radiance , & ! Input ! Temperature_AD, & ! Input ! Radiance_AD ) ! In/Output ! ! INPUT ARGUMENTS: ! SensorIndex: Sensor index id. This is a unique index associated ! with a (supported) sensor used to access the ! shared coefficient data for a particular sensor. ! See the ChannelIndex argument. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! ChannelIndex: Channel index id. This is a unique index associated ! with a (supported) sensor channel used to access the ! shared coefficient data for a particular sensor's ! channel. ! See the SensorIndex argument. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! Radiance: Radiance at which the adjoint radiance is desired. ! UNITS: mW/(m^2.sr.cm^-1) ! TYPE: REAL(fp) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! Temperature_AD: Adjoint Planck temperature. ! UNITS: Kelvin, K ! TYPE: REAL(fp) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN) ! ! OUTPUT ARGUMENTS: ! Radiance_AD: Adjoint radiance. ! UNITS: K.m^2.sr.cm^-1/mW ! TYPE: REAL(fp) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN OUT) ! ! SIDE EFFECTS: ! The input adjoint temperature argument, Temperature_AD, is NOT set to zero ! before returning to the calling routine. ! ! RESTRICTIONS: ! Spectral coefficients are obtained from the CRTM_SpcCoeff module ! so only temperatures for those sensors which are included in the spectral ! coefficient data file can be calculated. ! ! PROCEDURE: ! First the logarithm argument is calculated, ! ! a = pc1/R + 1 ! ! The inverse Planck function operator is then calculated, ! ! pc1 . pc2 ! F = ------------------------------ ! bc2 . a . ( R . LOG( a ) )^2 ! ! which is the derivate of the Planck temperature wrt radiance. The ! adjoint radiance is then determined from, ! ! R_AD = R_AD + ( F . T_AD ) ! ! where R_AD and T_AD on the LHS are the input adjoint radiance and ! temperature respectively. ! ! The bc1, bc2, pc1, and pc2 values are obtained from the ! CRTM_SpcCoeff module which is filled during the initialisation ! phase. ! !-------------------------------------------------------------------------------- SUBROUTINE CRTM_Planck_Temperature_AD( n, l , & ! Input Radiance , & ! Input Temperature_AD, & ! Input Radiance_AD ) ! In/Output ! Arguments INTEGER, INTENT(IN) :: n ! SensorIndex INTEGER, INTENT(IN) :: l ! ChannelIndex REAL(fp), INTENT(IN) :: Radiance REAL(fp), INTENT(IN) :: Temperature_AD REAL(fp), INTENT(IN OUT) :: Radiance_AD ! Local variables REAL(fp) :: Argument REAL(fp) :: F ! Calculate the Planck function operator ! ! The logarithm Argument Argument = ( SC(n)%Planck_C1(l) / Radiance ) + ONE ! The operator, call it F F = SC(n)%Planck_C1(l) * SC(n)%Planck_C2(l) / & ! ------------------------------------------------------------------- ( SC(n)%Band_C2(l) * Argument * ( Radiance * LOG( Argument ) )**2 ) ! Calculate the adjoint radiance Radiance_AD = Radiance_AD + ( F * Temperature_AD ) END SUBROUTINE CRTM_Planck_Temperature_AD END MODULE CRTM_Planck_Functions