72 '$Id: CRTM_AOD_Module.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $' 74 INTEGER,
PARAMETER ::
ml = 256
144 Atmosphere , & ! Input, M
145 ChannelInfo, & ! Input, M
146 RTSolution , & ! Output, L x M
148 result( error_status )
155 INTEGER :: error_status
157 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_AOD' 159 CHARACTER(ML) :: message
160 LOGICAL :: options_present
161 LOGICAL :: check_input
162 INTEGER :: n, n_sensors, sensorindex
163 INTEGER :: l, n_channels, channelindex
164 INTEGER :: m, n_profiles
178 n_sensors =
SIZE(channelinfo)
180 IF ( n_sensors == 0 .OR. n_channels == 0 )
RETURN 184 IF (
SIZE(rtsolution,dim=1) < n_channels )
THEN 186 WRITE( message,
'("Output RTSolution structure array too small (",i0,& 187 &") to hold results for the number of requested channels (",i0,")")') &
188 SIZE(rtsolution,dim=1), n_channels
196 n_profiles =
SIZE(atmosphere)
198 IF (
SIZE(rtsolution,dim=2) /= n_profiles )
THEN 200 message =
'Inconsistent profile dimensionality for RTSolution argument.' 205 options_present =
PRESENT(options)
206 IF ( options_present )
THEN 207 IF (
SIZE(options) /= n_profiles )
THEN 209 message =
'Inconsistent profile dimensionality for Options optional input argument.' 219 message =
'RTSolution output structure components have not been allocated' 228 profile_loop:
DO m = 1, n_profiles
234 WRITE( message,
'("The AerosolCoeff data must be loaded (with CRTM_Init routine) ", & 235 &"for the aerosol case profile #",i0)' ) m
243 IF (options_present)
THEN 244 check_input = options(m)%Check_Input
249 IF ( check_input )
THEN 252 WRITE( message,
'("Input data check failed for profile #",i0)' ) m
260 IF ( any(rtsolution(:,m)%n_Layers < atmosphere(m)%n_Layers) )
THEN 262 WRITE( message,
'("Number of RTSolution layers < Atmosphere for profile #",i0)' ) m
270 atmosphere(m)%n_Layers, &
275 WRITE( message,
'("Error allocating AtmOptics data structure for profile #",i0)' ) m
280 atmoptics%n_Legendre_Terms = 4
284 IF ( atmosphere(m)%n_Aerosols > 0 )
THEN 288 atmosphere(m)%n_Layers , &
289 atmosphere(m)%n_Aerosols )
299 sensor_loop:
DO n = 1, n_sensors
302 sensorindex = channelinfo(n)%Sensor_Index
308 channel_loop:
DO l = 1, channelinfo(n)%n_Channels
312 IF ( .NOT. channelinfo(n)%Process_Channel(l) ) cycle channel_loop
314 channelindex = channelinfo(n)%Channel_Index(l)
318 rtsolution(ln,m)%Sensor_Id = channelinfo(n)%Sensor_Id
319 rtsolution(ln,m)%WMO_Satellite_Id = channelinfo(n)%WMO_Satellite_Id
320 rtsolution(ln,m)%WMO_Sensor_Id = channelinfo(n)%WMO_Sensor_Id
321 rtsolution(ln,m)%Sensor_Channel = channelinfo(n)%Sensor_Channel(l)
329 IF ( atmosphere(m)%n_Aerosols > 0 )
THEN 335 IF ( error_status /=
success )
THEN 336 WRITE( message,
'("Error computing AerosolScatter for ",a,& 337 &", channel ",i0,", profile #",i0)' ) &
338 trim(channelinfo(n)%Sensor_ID), channelinfo(n)%Sensor_Channel(l), m
346 rtsolution(ln,m)%Layer_Optical_Depth(1:atmosphere(m)%n_Layers) = atmoptics%Optical_Depth
440 Atmosphere , & ! Input, M
441 Atmosphere_TL, & ! Input, M
442 ChannelInfo , & ! Input, M
443 RTSolution , & ! Output, L x M
444 RTSolution_TL, & ! Output, L x M
446 result( error_status )
455 INTEGER :: error_status
457 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_AOD_TL' 459 CHARACTER(ML) :: message
460 LOGICAL :: options_present
461 LOGICAL :: check_input
462 INTEGER :: status_fwd, status_tl
463 INTEGER :: n, n_sensors, sensorindex
464 INTEGER :: l, n_channels, channelindex
465 INTEGER :: m, n_profiles
479 n_sensors =
SIZE(channelinfo)
481 IF ( n_sensors == 0 .OR. n_channels == 0 )
RETURN 485 IF (
SIZE(rtsolution, dim=1) < n_channels .OR. &
486 SIZE(rtsolution_tl,dim=1) < n_channels )
THEN 488 WRITE( message,
'("Output RTSolution structure arrays too small (",i0,& 489 &") to hold results for the number of requested channels (",i0,")")') &
490 SIZE(rtsolution,dim=1), n_channels
497 n_profiles =
SIZE(atmosphere)
499 IF (
SIZE(atmosphere_tl) /= n_profiles .OR. &
500 SIZE(rtsolution, dim=2) /= n_profiles .OR. &
501 SIZE(rtsolution_tl,dim=2) /= n_profiles )
THEN 503 message =
'Inconsistent profile dimensionality for input arguments.' 508 options_present =
PRESENT(options)
509 IF ( options_present )
THEN 510 IF (
SIZE(options) /= n_profiles )
THEN 512 message =
'Inconsistent profile dimensionality for Options optional input argument.' 523 message =
'RTSolution output structure components have not been allocated' 532 profile_loop:
DO m = 1, n_profiles
538 WRITE( message,
'("The AerosolCoeff data must be loaded (with CRTM_Init routine) ", & 539 &"for the aerosol case profile #",i0)' ) m
547 IF (options_present)
THEN 548 check_input = options(m)%Check_Input
553 IF ( check_input )
THEN 556 WRITE( message,
'("Input data check failed for profile #",i0)' ) m
564 IF ( any(rtsolution(:,m)%n_Layers < atmosphere(m)%n_Layers) .OR. &
565 any(rtsolution_tl(:,m)%n_Layers < atmosphere(m)%n_Layers) )
THEN 567 WRITE( message,
'("Number of RTSolution layers < Atmosphere for profile #",i0)' ) m
575 atmosphere(m)%n_Layers, &
579 atmosphere(m)%n_Layers, &
585 WRITE( message,
'("Error allocating AtmOptics data structures for profile #",i0)' ) m
590 atmoptics%n_Legendre_Terms = 4
591 atmoptics_tl%n_Legendre_Terms = atmoptics%n_Legendre_Terms
595 IF ( atmosphere(m)%n_Aerosols > 0 )
THEN 599 atmosphere(m)%n_Layers , &
600 atmosphere(m)%n_Aerosols )
610 sensor_loop:
DO n = 1, n_sensors
613 sensorindex = channelinfo(n)%Sensor_Index
619 channel_loop:
DO l = 1, channelinfo(n)%n_Channels
623 IF ( .NOT. channelinfo(n)%Process_Channel(l) ) cycle channel_loop
625 channelindex = channelinfo(n)%Channel_Index(l)
629 rtsolution(ln,m)%Sensor_Id = channelinfo(n)%Sensor_Id
630 rtsolution(ln,m)%WMO_Satellite_Id = channelinfo(n)%WMO_Satellite_Id
631 rtsolution(ln,m)%WMO_Sensor_Id = channelinfo(n)%WMO_Sensor_Id
632 rtsolution(ln,m)%Sensor_Channel = channelinfo(n)%Sensor_Channel(l)
633 rtsolution_tl(ln,m)%Sensor_Id = rtsolution(ln,m)%Sensor_Id
634 rtsolution_tl(ln,m)%WMO_Satellite_Id = rtsolution(ln,m)%WMO_Satellite_Id
635 rtsolution_tl(ln,m)%WMO_Sensor_Id = rtsolution(ln,m)%WMO_Sensor_Id
636 rtsolution_tl(ln,m)%Sensor_Channel = rtsolution(ln,m)%Sensor_Channel
645 IF ( atmosphere(m)%n_Aerosols > 0 )
THEN 660 WRITE( message,
'("Error computing AerosolScatter for ",a,& 661 &", channel ",i0,", profile #",i0)' ) &
662 trim(channelinfo(n)%Sensor_ID), channelinfo(n)%Sensor_Channel(l), m
670 rtsolution(ln,m)%Layer_Optical_Depth(1:atmosphere(m)%n_Layers) = atmoptics%Optical_Depth
671 rtsolution_tl(ln,m)%Layer_Optical_Depth(1:atmosphere(m)%n_Layers) = atmoptics_tl%Optical_Depth
772 Atmosphere , & ! Input, M
773 RTSolution_AD, & ! Input, M
774 ChannelInfo , & ! Input, M
775 RTSolution , & ! Output, L x M
776 Atmosphere_AD, & ! Output, L x M
778 result( error_status )
787 INTEGER :: error_status
789 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_AOD_AD' 791 CHARACTER(ML) :: message
792 LOGICAL :: options_present
793 LOGICAL :: check_input
794 INTEGER :: status_fwd, status_ad
795 INTEGER :: n, n_sensors, sensorindex
796 INTEGER :: l, n_channels, channelindex
797 INTEGER :: m, n_profiles
812 n_sensors =
SIZE(channelinfo)
814 IF ( n_sensors == 0 .OR. n_channels == 0 )
RETURN 818 IF (
SIZE(rtsolution, dim=1) < n_channels .OR. &
819 SIZE(rtsolution_ad,dim=1) < n_channels )
THEN 821 WRITE( message,
'("Output RTSolution structure arrays too small (",i0,& 822 &") to hold results for the number of requested channels (",i0,")")') &
823 SIZE(rtsolution,dim=1), n_channels
830 n_profiles =
SIZE(atmosphere)
832 IF (
SIZE(atmosphere_ad) /= n_profiles .OR. &
833 SIZE(rtsolution, dim=2) /= n_profiles .OR. &
834 SIZE(rtsolution_ad,dim=2) /= n_profiles )
THEN 836 message =
'Inconsistent profile dimensionality for input arguments.' 841 options_present =
PRESENT(options)
842 IF ( options_present )
THEN 843 IF (
SIZE(options) /= n_profiles )
THEN 845 message =
'Inconsistent profile dimensionality for Options optional input argument.' 856 message =
'RTSolution output structure components have not been allocated' 865 profile_loop:
DO m = 1, n_profiles
871 WRITE( message,
'("The AerosolCoeff data must be loaded (with CRTM_Init routine) ", & 872 &"for the aerosol case profile #",i0)' ) m
880 IF (options_present)
THEN 881 check_input = options(m)%Check_Input
886 IF ( check_input )
THEN 889 WRITE( message,
'("Input data check failed for profile #",i0)' ) m
897 IF ( any(rtsolution(:,m)%n_Layers < atmosphere(m)%n_Layers) .OR. &
898 any(rtsolution_ad(:,m)%n_Layers < atmosphere(m)%n_Layers) )
THEN 900 WRITE( message,
'("Number of RTSolution layers < Atmosphere for profile #",i0)' ) m
908 atmosphere(m)%n_Layers, &
912 atmosphere(m)%n_Layers, &
918 WRITE( message,
'("Error allocating AtmOptics data structures for profile #",i0)' ) m
923 atmoptics%n_Legendre_Terms = 4
924 atmoptics_ad%n_Legendre_Terms = atmoptics%n_Legendre_Terms
928 IF ( atmosphere(m)%n_Aerosols > 0 )
THEN 932 atmosphere(m)%n_Layers , &
933 atmosphere(m)%n_Aerosols )
939 atmosphere_ad(m)%Climatology = atmosphere(m)%Climatology
941 atmosphere_ad(m)%Absorber_Id = atmosphere(m)%Absorber_Id
942 atmosphere_ad(m)%Absorber_Units = atmosphere(m)%Absorber_Units
944 DO na = 1, atmosphere(m)%n_Aerosols
945 atmosphere_ad(m)%Aerosol(na)%Type = atmosphere(m)%Aerosol(na)%Type
955 sensor_loop:
DO n = 1, n_sensors
959 sensorindex = channelinfo(n)%Sensor_Index
965 channel_loop:
DO l = 1, channelinfo(n)%n_Channels
969 IF ( .NOT. channelinfo(n)%Process_Channel(l) ) cycle channel_loop
971 channelindex = channelinfo(n)%Channel_Index(l)
975 rtsolution(ln,m)%Sensor_Id = channelinfo(n)%Sensor_Id
976 rtsolution(ln,m)%WMO_Satellite_Id = channelinfo(n)%WMO_Satellite_Id
977 rtsolution(ln,m)%WMO_Sensor_Id = channelinfo(n)%WMO_Sensor_Id
978 rtsolution(ln,m)%Sensor_Channel = channelinfo(n)%Sensor_Channel(l)
979 rtsolution_ad(ln,m)%Sensor_Id = rtsolution(ln,m)%Sensor_Id
980 rtsolution_ad(ln,m)%WMO_Satellite_Id = rtsolution(ln,m)%WMO_Satellite_Id
981 rtsolution_ad(ln,m)%WMO_Sensor_Id = rtsolution(ln,m)%WMO_Sensor_Id
982 rtsolution_ad(ln,m)%Sensor_Channel = rtsolution(ln,m)%Sensor_Channel
988 atmoptics_ad%Optical_Depth = rtsolution_ad(ln,m)%Layer_Optical_Depth(1:atmosphere(m)%n_Layers)
992 IF ( atmosphere(m)%n_Aerosols > 0 )
THEN 1007 WRITE( message,
'("Error computing AerosolScatter for ",a,& 1008 &", channel ",i0,", profile #",i0)' ) &
1009 trim(channelinfo(n)%Sensor_ID), channelinfo(n)%Sensor_Channel(l), m
1017 rtsolution(ln,m)%Layer_Optical_Depth(1:atmosphere(m)%n_Layers) = atmoptics%Optical_Depth
1119 Atmosphere , & ! Input, M
1120 RTSolution_K, & ! Input, M
1121 ChannelInfo , & ! Input, M
1122 RTSolution , & ! Output, L x M
1123 Atmosphere_K, & ! Output, L x M
1125 result( error_status )
1134 INTEGER :: error_status
1136 CHARACTER(*),
PARAMETER :: routine_name =
'CRTM_AOD_K' 1138 CHARACTER(ML) :: message
1139 LOGICAL :: options_present
1140 LOGICAL :: check_input
1141 INTEGER :: status_fwd, status_k
1142 INTEGER :: n, n_sensors, sensorindex
1143 INTEGER :: l, n_channels, channelindex
1144 INTEGER :: m, n_profiles
1159 n_sensors =
SIZE(channelinfo)
1161 IF ( n_sensors == 0 .OR. n_channels == 0 )
RETURN 1165 IF (
SIZE(rtsolution ,dim=1) < n_channels .OR. &
1166 SIZE(atmosphere_k,dim=1) < n_channels .OR. &
1167 SIZE(rtsolution_k,dim=1) < n_channels )
THEN 1169 WRITE( message,
'("RTSolution and K-matrix (Atm,RT) structure arrays too small (",& 1170 &2(i0,","),i0,") for the number of requested channels (",i0,")")') &
1171 SIZE(rtsolution ,dim=1), &
1172 SIZE(atmosphere_k,dim=1), &
1173 SIZE(rtsolution_k,dim=1), &
1182 n_profiles =
SIZE(atmosphere)
1184 IF (
SIZE(rtsolution_k,dim=2) /= n_profiles .OR. &
1185 SIZE(atmosphere_k,dim=2) /= n_profiles .OR. &
1186 SIZE(rtsolution ,dim=2) /= n_profiles )
THEN 1188 message =
'Inconsistent profile dimensionality for input arguments.' 1193 options_present =
PRESENT(options)
1194 IF ( options_present )
THEN 1195 IF (
SIZE( options ) /= n_profiles )
THEN 1197 message =
'Inconsistent profile dimensionality for Options optional input argument.' 1208 message =
'RTSolution output structure components have not been allocated' 1217 profile_loop:
DO m = 1, n_profiles
1223 WRITE( message,
'("The AerosolCoeff data must be loaded (with CRTM_Init routine) ", & 1224 &"for the aerosol case profile #",i0)' ) m
1231 check_input = .true.
1232 IF (options_present)
THEN 1233 check_input = options(m)%Check_Input
1238 IF ( check_input )
THEN 1241 WRITE( message,
'("Input data check failed for profile #",i0)' ) m
1249 IF ( any(rtsolution(:,m)%n_Layers < atmosphere(m)%n_Layers) .OR. &
1250 any(rtsolution_k(:,m)%n_Layers < atmosphere(m)%n_Layers) )
THEN 1252 WRITE( message,
'("Number of RTSolution layers < Atmosphere for profile #",i0)' ) m
1260 atmosphere(m)%n_Layers, &
1264 atmosphere(m)%n_Layers, &
1270 WRITE( message,
'("Error allocating AtmOptics data structures for profile #",i0)' ) m
1275 atmoptics%n_Legendre_Terms = 4
1276 atmoptics_k%n_Legendre_Terms = atmoptics%n_Legendre_Terms
1280 IF ( atmosphere(m)%n_Aerosols > 0 )
THEN 1284 atmosphere(m)%n_Layers , &
1285 atmosphere(m)%n_Aerosols )
1295 sensor_loop:
DO n = 1, n_sensors
1299 sensorindex = channelinfo(n)%Sensor_Index
1305 channel_loop:
DO l = 1, channelinfo(n)%n_Channels
1309 IF ( .NOT. channelinfo(n)%Process_Channel(l) ) cycle channel_loop
1311 channelindex = channelinfo(n)%Channel_Index(l)
1315 rtsolution(ln,m)%Sensor_Id = channelinfo(n)%Sensor_Id
1316 rtsolution(ln,m)%WMO_Satellite_Id = channelinfo(n)%WMO_Satellite_Id
1317 rtsolution(ln,m)%WMO_Sensor_Id = channelinfo(n)%WMO_Sensor_Id
1318 rtsolution(ln,m)%Sensor_Channel = channelinfo(n)%Sensor_Channel(l)
1319 rtsolution_k(ln,m)%Sensor_Id = rtsolution(ln,m)%Sensor_Id
1320 rtsolution_k(ln,m)%WMO_Satellite_Id = rtsolution(ln,m)%WMO_Satellite_Id
1321 rtsolution_k(ln,m)%WMO_Sensor_Id = rtsolution(ln,m)%WMO_Sensor_Id
1322 rtsolution_k(ln,m)%Sensor_Channel = rtsolution(ln,m)%Sensor_Channel
1327 atmosphere_k(ln,m)%Climatology = atmosphere(m)%Climatology
1329 atmosphere_k(ln,m)%Absorber_Id = atmosphere(m)%Absorber_Id
1330 atmosphere_k(ln,m)%Absorber_Units = atmosphere(m)%Absorber_Units
1332 DO na = 1, atmosphere(m)%n_Aerosols
1333 atmosphere_k(ln,m)%Aerosol(na)%Type = atmosphere(m)%Aerosol(na)%Type
1340 atmoptics_k%Optical_Depth = rtsolution_k(ln,m)%Layer_Optical_Depth(1:atmosphere(m)%n_Layers)
1344 IF ( atmosphere(m)%n_Aerosols > 0 )
THEN 1355 atmosphere_k(ln,m), &
1359 WRITE( message,
'("Error computing AerosolScatter for ",a,& 1360 &", channel ",i0,", profile #",i0)' ) &
1361 trim(channelinfo(n)%Sensor_ID), channelinfo(n)%Sensor_Channel(l), m
1369 rtsolution(ln,m)%Layer_Optical_Depth(1:atmosphere(m)%n_Layers) = atmoptics%Optical_Depth
1409 CHARACTER(*),
INTENT(OUT) :: id
integer function, public crtm_compute_aerosolscatter_ad(Atm, AScat, AScat_AD, SensorIndex, ChannelIndex, Atm_AD, ASV)
logical function, public crtm_aerosolcoeff_isloaded()
integer, parameter, public failure
integer function, public crtm_aod_tl(Atmosphere, Atmosphere_TL, ChannelInfo, RTSolution, RTSolution_TL, Options)
integer function, public crtm_aod_ad(Atmosphere, RTSolution_AD, ChannelInfo, RTSolution, Atmosphere_AD, Options)
real(fp), parameter, public zero
integer, parameter, public max_n_phase_elements
integer function, public crtm_compute_aerosolscatter_tl(Atm, AScat, Atm_TL, SensorIndex, ChannelIndex, AScat_TL, ASV)
subroutine, public crtm_aod_version(Id)
logical function, public crtm_atmosphere_isvalid(Atm)
elemental subroutine, public crtm_atmoptics_destroy(self)
integer, parameter, public max_n_legendre_terms
elemental logical function, public crtm_atmoptics_associated(self)
elemental subroutine, public crtm_atmoptics_zero(self)
integer function, public crtm_compute_aerosolscatter(Atm, SensorIndex, ChannelIndex, AScat, ASV)
integer function, public crtm_aod(Atmosphere, ChannelInfo, RTSolution, Options)
elemental logical function, public crtm_rtsolution_associated(RTSolution)
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
elemental subroutine, public asvar_destroy(self)
elemental subroutine, public crtm_atmoptics_create(self, n_Layers, n_Legendre_Terms, n_Phase_Elements)
character(*), parameter module_version_id
elemental logical function, public asvar_associated(self)
elemental integer function, public crtm_channelinfo_n_channels(ChannelInfo)
elemental subroutine, public asvar_create(self, n_Legendre_Terms, n_Phase_Elements, n_Layers, n_Aerosols)
integer, parameter, public success
integer function, public crtm_aod_k(Atmosphere, RTSolution_K, ChannelInfo, RTSolution, Atmosphere_K, Options)