10 use ai_wavelength_grid,
only : wavelength_grid_t
11 use musica_constants,
only : musica_dk
12 use musica_lookup_2d_axis,
only : lookup_2d_axis_t
13 use musica_string,
only : string_t
34 type(string_t) :: parameter_name_
35 logical :: is_loaded_ = .false.
38 real(kind=musica_dk),
allocatable :: values_(:,:,:,:)
51 integer :: number_of_chebyshev_coefficients_ = 0
52 type(wavelength_grid_t) :: grid_
53 real(kind=musica_dk) :: minimum_ln_radius_ = 0.0
54 real(kind=musica_dk) :: maximum_ln_radius_ = 0.0
55 type(lookup_2d_axis_t),
allocatable :: axes_(:)
57 procedure :: get_optics
78 use musica_assert,
only : assert, assert_msg
79 use musica_config,
only : config_t
80 use musica_lookup_axis,
only : lookup_axis_t
81 use musica_io,
only : io_t
82 use musica_io_netcdf,
only : io_netcdf_t
85 class(config_t),
intent(inout) :: config
87 character(len=*),
parameter :: my_name =
"optics_lookup_t constructor"
88 class(io_t),
pointer :: lookup_file
89 type(config_t) :: grid_config
90 type(string_t) :: file_path, variable_name, axis_real_name, axis_imag_name
91 type(lookup_axis_t) :: axis_real, axis_imag
92 real(kind=musica_dk),
allocatable :: axis_real_values(:,:), axis_imag_values(:,:)
96 call config%get(
"file path", file_path, my_name )
97 lookup_file => io_netcdf_t( file_path )
98 call config%get(
"grid", grid_config, my_name )
99 call new_lookup%set_grid( grid_config, lookup_file )
100 call config%get(
"real axis", axis_real_name, my_name )
101 call lookup_file%read( axis_real_name, axis_real_values, my_name )
102 call config%get(
"imaginary axis", axis_imag_name, my_name )
103 call lookup_file%read( axis_imag_name, axis_imag_values, my_name )
104 call assert_msg( 756675500,
size( axis_real_values, 2 ) .eq. &
105 size( axis_imag_values, 2 ), &
106 "Optics lookup axis dimension mismatch" )
107 allocate( new_lookup%axes_( new_lookup%grid_%number_of_sections( ) ) )
108 do i_band = 1, new_lookup%grid_%number_of_sections( )
109 axis_real = lookup_axis_t( axis_real_name, axis_real_values( :,
i_band ) )
110 axis_imag = lookup_axis_t( axis_imag_name, axis_imag_values( :,
i_band ) )
111 new_lookup%axes_(
i_band ) = lookup_2d_axis_t( axis_real, axis_imag )
113 variable_name =
"minimum_radius"
114 call lookup_file%read( variable_name, &
115 new_lookup%minimum_ln_radius_, my_name )
116 new_lookup%minimum_ln_radius_ = log( new_lookup%minimum_ln_radius_ )
117 variable_name =
"maximum_radius"
118 call lookup_file%read( variable_name, &
119 new_lookup%maximum_ln_radius_, my_name )
120 new_lookup%maximum_ln_radius_ = log( new_lookup%maximum_ln_radius_ )
122 optics_data_t(
"specific absorption lookup", lookup_file, config )
124 optics_data_t(
"specific extinction lookup", lookup_file, config )
126 optics_data_t(
"asymmetry factor lookup", lookup_file, config )
128 if( .not. new_lookup%data_( i_param )%is_loaded_ ) cycle
129 if( new_lookup%number_of_chebyshev_coefficients_ .eq. 0 )
then
130 new_lookup%number_of_chebyshev_coefficients_ = &
131 size( new_lookup%data_( i_param )%values_, 1 )
133 call assert_msg( 168034110, &
134 size( new_lookup%data_( i_param )%values_, 1 ) &
135 .eq. new_lookup%number_of_chebyshev_coefficients_, &
136 "Dimension mismatch in optics_lookup_t data" )
138 call assert_msg( 531859329, &
139 size( new_lookup%data_( i_param )%values_, 2 ) &
140 .eq. axis_real%size( ), &
141 "Dimension mismatch in optics_lookup_t data" )
142 call assert_msg( 521820197, &
143 size( new_lookup%data_( i_param )%values_, 3 ) &
144 .eq. axis_imag%size( ), &
145 "Dimension mismatch in optics_lookup_t data" )
146 call assert_msg( 284936197, &
147 size( new_lookup%data_( i_param )%values_, 4 ) &
148 .eq. new_lookup%grid_%number_of_sections( ), &
149 "Dimension mismatch in optics_lookup_t data" )
151 deallocate( lookup_file )
163 pure subroutine get_optics( this, refractive_indices, absorption, &
164 extinction, asymmetry_factor )
168 complex(kind=musica_dk),
intent(in) :: refractive_indices(:)
171 real(kind=musica_dk),
optional,
intent(out) ::
absorption(:,:)
172 real(kind=musica_dk),
optional,
intent(out) ::
extinction(:,:)
179 do i_band = 1, this%grid_%number_of_sections( )
180 associate( axis => this%axes_(
i_band ) )
182 call axis%find( (/real( refractive_indices(
i_band ) ), &
183 abs( aimag( refractive_indices(
i_band ) ) )/), &
201 end subroutine get_optics
216 real(kind=musica_dk),
intent(in) :: radius__m
218 associate( rmin => this%minimum_ln_radius_, &
219 rmax => this%maximum_ln_radius_ )
278 type(wavelength_grid_t) function
grid( this )
295 use ai_wavelength_grid,
only : kcentimeter, kwavenumber
296 use musica_assert,
only : assert_msg
297 use musica_config,
only : config_t
298 use musica_io,
only : io_t
301 class(config_t),
intent(inout) :: config
302 class(io_t),
intent(inout) :: lookup_file
304 character(len=*),
parameter :: my_name =
"optics_lookup_t grid loader"
305 type(string_t) :: var_name, lb_units, ub_units
306 real(kind=musica_dk),
allocatable :: lower_bounds(:), upper_bounds(:)
308 call config%get(
"lower bounds", var_name, my_name )
309 call lookup_file%read( var_name, lower_bounds, my_name )
310 lb_units = lookup_file%variable_units( var_name, my_name )
311 call config%get(
"upper bounds", var_name, my_name )
312 call lookup_file%read( var_name, upper_bounds, my_name )
313 ub_units = lookup_file%variable_units( var_name, my_name )
314 call assert_msg( 950480637, lb_units .eq. ub_units, &
315 "Units mismatch for upper and lower wavelength "// &
317 call assert_msg( 709050082, lb_units .eq.
"cm-1", &
318 "Expected wavlength bounds in units of 'cm-1'" )
319 this%grid_ = wavelength_grid_t( lower_bounds = lower_bounds, &
320 upper_bounds = upper_bounds, &
321 bounds_in = kwavenumber, &
322 base_unit = kcentimeter )
332 use musica_config,
only : config_t
333 use musica_io,
only : io_t
336 character(len=*),
intent(in) :: parameter_name
337 class(io_t),
intent(inout) :: lookup_file
338 class(config_t),
intent(inout) :: config
340 character(len=*),
parameter :: my_name =
"optics table loader"
341 type(config_t) :: table_config
342 type(string_t) :: variable_name
345 new_data%parameter_name_ = parameter_name
346 call config%get( parameter_name, table_config, my_name, found = found )
347 if( .not. found )
then
348 allocate( new_data%values_(0,0,0,0) )
351 call table_config%get(
"variable name", variable_name, my_name )
352 call lookup_file%read( variable_name, new_data%values_, my_name )
353 new_data%is_loaded_ = .true.
361 axis, chebyshev_values )
364 integer,
intent(in) :: band_index
365 integer,
intent(in) ::
indices(2)
366 real(kind=musica_dk),
intent(in) ::
residuals(2)
367 type(lookup_2d_axis_t),
intent(in) :: axis
368 real(kind=musica_dk),
intent(out) :: chebyshev_values(:)
370 call axis%interpolate( this%values_( :, &
The optics_lookup_t type and related functions.
integer elemental function number_of_chebyshev_coefficients(this)
Returns the number of Chebyshev coefficients per band and property.
subroutine set_grid(this, config, lookup_file)
Sets the wavelength grid for an optics_lookup_t object.
integer, parameter knumberofparameters
Number of possible optics parameters.
type(optics_lookup_t) function constructor(config)
Constructor of optics lookup objects.
integer elemental function number_of_wavelength_bands(this)
Returns the number of wavelength bands for each property.
pure subroutine optics_data_lookup(this, band_index, indices, residuals, axis, chebyshev_values)
Looks up optical property data at a given wavelength band.
type(optics_data_t) function optics_data_constructor(parameter_name, lookup_file, config)
Constructor of optics lookup data objects.
real(kind=musica_dk) elemental function normalize_radius(this, radius__m)
Normalizes a radius to the range used to calculate the Chebychev coefficients.
real(kind=musica_dk) elemental function minimum_radius__m(this)
Returns the minimum radius of the range used to calculate the Chebychev coefficients.
integer, parameter kextinction
integer, parameter kasymmetryfactor
real(kind=musica_dk) elemental function maximum_radius__m(this)
Returns the maximum radius of the range used to calculate the Chebychev coefficients.
type(wavelength_grid_t) function grid(this)
Returns the wavelength grid that the properties are returned on.
integer, parameter kabsorption
real(kind=musica_dk), dimension(:,:), intent(out), optional asymmetry_factor
real(kind=musica_dk), dimension(:,:), intent(out), optional absorption
integer, dimension(2) indices
real(kind=musica_dk), dimension(2) residuals
real(kind=musica_dk), dimension(:,:), intent(out), optional extinction