28   REAL(fp),
PARAMETER:: &
    29        &ttp = 2.7316e+2_fp, &
    30        &psat = 6.1078e+2_fp,&
    34        &cliq = 4.1855e+3_fp,&
    35        &csol = 2.1060e+3_fp,&
    36        &cvap = 1.8460e+3_fp,&
    37        &hvap = 2.5000e+6_fp,&
    38        &hfus = 3.3358e+5_fp,&
    41   REAL(fp),
PARAMETER ::  &
    50        &xb = xa+hvap/(rv*ttp),&
    51        &xbi = xai+hsub/(rv*ttp)
    68     class(ufo_aod),    
intent(in)    :: self
    69     type(ufo_geovals), 
intent(in)    :: geovals
    70     real(kind_real),  
intent(inout) :: hofx(:)
    71     type(c_ptr), 
value, 
intent(in)    :: obss
    73     real(kind_real), 
allocatable :: Aod_Obs(:,:)
    74     real(kind_real), 
allocatable :: Omg_Aod(:,:)
    83     CHARACTER(*), 
PARAMETER :: PROGRAM_NAME   = 
'ufo_aod_mod.F90'    93     CHARACTER(*), 
PARAMETER :: ENDIAN_TYPE=
'little_endian'    94     CHARACTER(*), 
PARAMETER :: COEFFICIENT_PATH=
'Data/'   100     INTEGER, 
PARAMETER :: N_ABSORBERS = 2  
   101     INTEGER, 
PARAMETER :: N_CLOUDS    = 0  
   102     INTEGER, 
PARAMETER :: n_aerosols_gocart_crtm = 14,n_aerosols=n_aerosols_gocart_crtm
   105     INTEGER :: N_PROFILES 
   110     INTEGER     , 
PARAMETER :: N_SENSORS = 1  
   111     CHARACTER(*), 
PARAMETER :: SENSOR_ID(N_SENSORS) = (/
'v.viirs-m_npp'/)  
   113     CHARACTER(max_string) :: err_msg
   119     CHARACTER(256) :: message, version
   120     INTEGER        :: err_stat, alloc_stat
   121     INTEGER        :: n_channels
   122     INTEGER        :: l, m, n, nc, i,k
   132     TYPE(CRTM_ChannelInfo_type)             :: chinfo(N_SENSORS)
   137     TYPE(CRTM_Atmosphere_type), 
ALLOCATABLE :: atm(:)
   138     TYPE(CRTM_RTSolution_type), 
ALLOCATABLE :: rts(:,:)
   143     TYPE(CRTM_Atmosphere_type), 
ALLOCATABLE :: atm_K(:,:)
   144     TYPE(CRTM_RTSolution_type), 
ALLOCATABLE :: rts_K(:,:)
   147     TYPE(CRTM_Aerosol_type), 
ALLOCATABLE :: aerosols(:)
   149     TYPE(ufo_geoval), 
pointer :: geoval
   150     character(MAXVARLEN) :: varname
   156     character(len=3)     :: chan_num
   157     character(len=100)   :: var_name
   158     REAL(fp), 
allocatable :: rmse(:)
   159     real(fp), 
allocatable :: diff(:,:)
   160     real(kind_real), 
allocatable :: ztmp(:)
   168     n_profiles=geovals%nobs
   174        n_layers=
SIZE(geoval%vals,1)
   176        err_msg=trim(varname)//
' not found - Stopping'   177        CALL abor1_ftn(err_msg)
   181     ALLOCATE(atm(n_profiles),aerosols(n_aerosols))
   185     CALL program_message( program_name, &
   186          'Check/example program for the CRTM Forward and K-Matrix functions using '//&
   187          ENDIAN_TYPE//
' coefficient datafiles', &
   188          'CRTM Version: '//trim(version) )
   197     WRITE( *,
'(/5x,"Initializing the CRTM...")' )
   198     err_stat = crtm_init( sensor_id, &
   200          file_path=coefficient_path, &
   202     IF ( err_stat /= success ) 
THEN   203        message = 
'Error initializing CRTM'   204        CALL display_message( program_name, message, failure )
   210     n_channels = sum(crtm_channelinfo_n_channels(chinfo))
   223     sensor_loop: 
DO n = 1, n_sensors
   231        n_channels = crtm_channelinfo_n_channels(chinfo(n))
   235        ALLOCATE( rts( n_channels, n_profiles ), &
   236             atm_k( n_channels, n_profiles ), &
   237             rts_k( n_channels, n_profiles ), &
   239        IF ( alloc_stat /= 0 ) 
THEN   240           message = 
'Error allocating structure arrays'   241           CALL display_message( program_name, message, failure )
   250        CALL crtm_atmosphere_create( atm, n_layers, n_absorbers, n_clouds, n_aerosols )
   251        IF ( any(.NOT. crtm_atmosphere_associated(atm)) ) 
THEN   252           message = 
'Error allocating CRTM Forward Atmosphere structure'   253           CALL display_message( program_name, message, failure )
   258        CALL crtm_atmosphere_create( atm_k, n_layers, n_absorbers, n_clouds, n_aerosols )
   259        IF ( any(.NOT. crtm_atmosphere_associated(atm_k)) ) 
THEN   260           message = 
'Error allocating CRTM K-matrix Atmosphere structure'   261           CALL display_message( program_name, message, failure )
   265        CALL crtm_rtsolution_create(rts, n_layers )
   266        CALL crtm_rtsolution_create(rts_k, n_layers )
   287        CALL crtm_atmosphere_zero( atm_k )
   292        rts_k%Radiance               = 
zero   293        rts_k%Brightness_Temperature = 
zero   297              rts_k(l,m)%layer_optical_depth = 
one   306        call crtm_atmosphere_inspect(atm)
   307        call crtm_channelinfo_inspect(chinfo(1))
   311        err_stat = crtm_aod_k( atm,    &  
   316        IF ( err_stat /= success ) 
THEN   317           message = 
'Error calling CRTM K-Matrix Model for '//trim(sensor_id(n))
   318           CALL display_message( program_name, message, failure )
   330        ALLOCATE(diff(n_channels,n_profiles),rmse(n_channels))
   332        allocate(aod_obs(n_profiles, n_channels))
   333        allocate(omg_aod(n_profiles, n_channels))
   335          write(chan_num, 
'(I0)') l
   337          var_name = 
'aerosol_optical_depth_' // trim(chan_num) // 
'_'   340          var_name = 
'obs_minus_forecast_unadjusted_' // trim(chan_num) // 
'_'   347              diff(l,m) = sum(rts(l,m)%layer_optical_depth(:)) - (aod_obs(m,l) - omg_aod(m,l))
   348              rmse(l) = rmse(l) + diff(l,m)**2
   352        rmse=sqrt(rmse/n_profiles)
   354        print *,
'N_profiles', n_profiles
   356           print *, 
'Channel: ',l
   357           print *, 
'Max difference: ', maxval(abs(diff(l,:)))
   358           print *, 
'RMSE: ', rmse(l)
   361        DEALLOCATE(diff,rmse)
   371             hofx(i) = sum(rts(l,m)%layer_optical_depth)
   380        CALL crtm_atmosphere_destroy(atm_k)
   381        CALL crtm_atmosphere_destroy(atm)
   382        CALL crtm_rtsolution_destroy(rts_k)
   383        CALL crtm_rtsolution_destroy(rts)
   389        DEALLOCATE(rts, rts_k, atm_k, stat = alloc_stat)
   390        IF ( alloc_stat /= 0 ) 
THEN   391           message = 
'Error allocating structure arrays'   392           CALL display_message( program_name, message, failure )
   402     WRITE( *, 
'( /5x, "Destroying the CRTM..." )' )
   403     err_stat = crtm_destroy( chinfo )
   404     IF ( err_stat /= success ) 
THEN   405        message = 
'Error destroying CRTM'   406        CALL display_message( program_name, message, failure )
   445       IF (geoval%vals(1,k1) > geoval%vals(n_layers,k1)) 
THEN    456             atm(k1)%Temperature(1:n_layers) = geoval%vals(n_layers:1:-1,k1)
   458             atm(k1)%Temperature(1:n_layers) = geoval%vals(:,k1) 
   465             atm(k1)%Pressure(1:n_layers) = geoval%vals(n_layers:1:-1,k1)
   467             atm(k1)%Pressure(1:n_layers) = geoval%vals(:,k1) 
   475             atm(k1)%Level_Pressure(0:n_layers) = geoval%vals(n_layers+1:1:-1,k1)
   477             atm(k1)%Level_Pressure(0:n_layers) = geoval%vals(:,k1)
   481          atm(k1)%Climatology         = us_standard_atmosphere
   483          atm(k1)%Absorber_Id(1:1)    = (/ h2o_id /)
   484          atm(k1)%Absorber_Units(1:1) = (/ mass_mixing_ratio_units /)
   488             atm(k1)%Absorber(1:n_layers,1)       = geoval%vals(n_layers:1:-1,k1)
   490             atm(k1)%Absorber(1:n_layers,1)       = geoval%vals(:,k1) 
   494          atm(k1)%Absorber_Id(2:2)    = (/ o3_id /)
   495          atm(k1)%Absorber_Units(2:2) = (/ volume_mixing_ratio_units /)
   496          atm(k1)%Absorber(1:n_layers,2)=1.e-10
   507       REAL(fp), 
DIMENSION(N_LAYERS) :: ugkg_kgm2,qsat,rh,prsl,tsen,p25
   517       CHARACTER(len=MAXVARLEN) :: varname
   519       INTEGER :: n_aerosols_all
   527             ugkg_kgm2(k)=1.0e-9_fp*(atm(m)%Level_Pressure(k)-&
   528                  &atm(m)%Level_Pressure(k-1))*100_fp/
grav   529             prsl(k)=atm(m)%Pressure(n_layers-k+1)*0.1_fp 
   530             tsen(k)=atm(m)%Temperature(n_layers-k+1)
   536             rh(k)=atm(m)%Absorber(k,1)*1.e-3_fp/&
   544             DO i=1,n_aerosols_all
   546                IF (trim(varname) == 
'p25') 
THEN   550                      p25(1:n_layers)=geoval%vals(n_layers:1:-1,m)
   552                      p25(1:n_layers)=geoval%vals(1:n_layers,m)
   567          DO i=1,n_aerosols_all
   569             IF (trim(varname) == 
'p25') cycle
   574                atm(m)%aerosol(ii)%Concentration(1:n_layers)=geoval%vals(n_layers:1:-1,m)
   576                atm(m)%aerosol(ii)%Concentration(1:n_layers)=geoval%vals(1:n_layers,m)
   579             atm(m)%aerosol(ii)%Concentration=
max(atm(m)%aerosol(ii)%Concentration*ugkg_kgm2,&
   582             SELECT CASE ( trim(varname))
   584                atm(m)%aerosol(ii)%type  = sulfate_aerosol
   587                   atm(m)%Aerosol(ii)%Effective_Radius(k)=&
   593                atm(m)%aerosol(ii)%type  = black_carbon_aerosol
   594                atm(m)%Aerosol(ii)%Effective_Radius(:)=&
   595                     &
aeroc%Reff(1,atm(m)%aerosol(ii)%type)
   597                atm(m)%aerosol(ii)%type  = black_carbon_aerosol
   599                   atm(m)%Aerosol(ii)%Effective_Radius(k)=&
   605                atm(m)%aerosol(ii)%type  = organic_carbon_aerosol
   606                atm(m)%Aerosol(ii)%Effective_Radius(:)=&
   607                     &
aeroc%Reff(1,atm(m)%aerosol(ii)%type)
   609                atm(m)%aerosol(ii)%type  = organic_carbon_aerosol
   611                   atm(m)%Aerosol(ii)%Effective_Radius(k)=&
   617                atm(m)%aerosol(ii)%type  = dust_aerosol
   618                atm(m)%Aerosol(ii)%Effective_Radius(:)=0.55_fp
   619                atm(m)%aerosol(ii)%Concentration=&
   620                     &atm(m)%aerosol(ii)%Concentration+0.78_fp*p25
   622                atm(m)%aerosol(ii)%type  = dust_aerosol
   623                atm(m)%Aerosol(ii)%Effective_Radius(:)=1.4_fp
   624                atm(m)%aerosol(ii)%Concentration=&
   625                     &atm(m)%aerosol(ii)%Concentration+0.22_fp*p25
   627                atm(m)%aerosol(ii)%type  = dust_aerosol
   628                atm(m)%Aerosol(ii)%Effective_Radius(:)=2.4_fp
   630                atm(m)%aerosol(ii)%type  = dust_aerosol
   631                atm(m)%Aerosol(ii)%Effective_Radius(:)=4.5_fp
   633                atm(m)%aerosol(ii)%type  = dust_aerosol
   634                atm(m)%Aerosol(ii)%Effective_Radius(:)=8.0_fp
   637                atm(m)%aerosol(ii)%type  = seasalt_ssam_aerosol
   639                   atm(m)%Aerosol(ii)%Effective_Radius(k)=&
   644                atm(m)%aerosol(ii)%type  = seasalt_sscm1_aerosol
   646                   atm(m)%Aerosol(ii)%Effective_Radius(k)=&
   651                atm(m)%aerosol(ii)%type  = seasalt_sscm2_aerosol
   653                   atm(m)%Aerosol(ii)%Effective_Radius(k)=&
   658                atm(m)%aerosol(ii)%type  = seasalt_sscm3_aerosol
   660                   atm(m)%Aerosol(ii)%Effective_Radius(k)=&
   681       INTEGER ,
INTENT(in) :: itype
   682       REAL(fp)    ,
INTENT(in) :: eh
   689       IF ( eh <= 
aeroc%RH(1) ) 
THEN   694          DO k = 1, 
aeroc%n_RH-1
   695             IF ( eh < 
aeroc%RH(k+1) .AND. eh > 
aeroc%RH(k) ) 
THEN   705          r_eff = 
aeroc%Reff(j1,itype )
   707          r_eff = (1.0_fp-h1)*
aeroc%Reff(j1,itype ) + h1*
aeroc%Reff(j2,itype )
   714     SUBROUTINE genqsat(qsat,tsen,prsl,nsig,ice)
   736       LOGICAL                               ,
INTENT(in   ) :: ice
   737       REAL(fp),
DIMENSION(nsig), 
INTENT(  out) :: qsat
   738       REAL(fp),
DIMENSION(nsig),
INTENT(in   ) :: tsen,prsl
   739       INTEGER                       ,
INTENT(in   ) :: nsig
   743       REAL(fp) pw,tdry,tr,es,es2
   744       REAL(fp) w,onep3,esmax
   745       REAL(fp) desidt,deswdt,dwdt,desdt,esi,esw
   746       REAL(fp) :: mint,estmax
   755          IF((prsl(k) < 30._fp .AND.  &
   756               prsl(k) > 2._fp) .AND.  &
   766       IF (tdry >= 
ttp .OR. .NOT. ice) 
THEN   768       ELSEIF (tdry < 
tmix) 
THEN   780          IF (tdry >= 
ttp .OR. .NOT. ice) 
THEN   782          ELSEIF (tdry < 
tmix) 
THEN   796             esmax=
min(esmax,estmax)
   799          qsat(k) = 
eps * es2 / (pw - 
omeps * es2)
 
subroutine, public ufo_geovals_get_var(self, varname, geoval, status)
character(len=maxvarlen), public var_mixr
real(fp), parameter, public zero
integer, parameter, public naerosols_gocart_esrl
character(len=maxvarlen), dimension(naerosols_gocart_esrl), public var_aerosols
character(len=maxvarlen), public var_prsi
real(fp), parameter omeps
real(fp) function gocart_aerosol_size(itype, eh)
integer, parameter max_string
integer function, public obsspace_get_nobs(c_dom)
Return the number of observations. 
subroutine genqsat(qsat, tsen, prsl, nsig, ice)
type(aerosolcoeff_type), target, save, public aeroc
Fortran module to handle aod observations. 
Fortran derived type for aod trajectory. 
real(fp), parameter, public one
subroutine load_aerosol_data()
subroutine load_atm_data()
character(len=maxvarlen), public var_prs
subroutine crtm_version(version)
real, parameter, public small_value
logical, parameter ice4qsat
Fortran module handling observation locations. 
character(len=maxvarlen), public var_t
Fortran interface to ObsSpace. 
subroutine ufo_aod_simobs(self, geovals, hofx, obss)
integer function, public obsspace_get_nlocs(c_dom)
Return the number of observational locations.