14 use fckit_log_module,
only : fckit_log
26 integer,
pointer :: channels(:) => null()
27 real(kind_real),
pointer :: mean(:) => null()
28 real(kind_real),
pointer :: pcmin(:) => null()
29 real(kind_real),
pointer :: pcmax(:) => null()
30 real(kind_real),
pointer :: pcguess(:) => null()
31 real(kind_real),
pointer :: ev(:,:) => null()
32 real(kind_real),
pointer :: ev_inverse(:,:) => null()
40 real(kind_real) :: gridstep
41 real(kind_real),
POINTER :: emispc(:,:,:)
49 logical :: initialised = .false.
76 character(len=*),
intent(in) :: filepath
77 character(len=*),
intent(in),
optional :: atlaspath
79 character(len=*),
parameter :: routinename =
"ufo_rttovonedvarcheck_InitPCEmis"
80 logical :: file_exists
84 inquire(file=trim(filepath), exist=file_exists)
87 open(unit = fileunit, file = trim(filepath))
89 close(unit = fileunit)
90 call fckit_log % info(
"rttovonedvarcheck EmisEigenVec file exists and read in")
92 call abor1_ftn(
"rttovonedvarcheck EmisEigenVec file not found: aborting")
95 self % initialised = .true.
99 if (
present(atlaspath))
then
100 inquire(file=trim(atlaspath), exist=file_exists)
101 if (file_exists)
then
103 open(unit = fileunit, file = trim(filepath))
105 close(unit = fileunit)
106 call fckit_log % info(
"rttovonedvarcheck Emis Atlas file exists and read in")
108 call abor1_ftn(
"rttovonedvarcheck Emis Atlas file not found but requested: aborting")
132 integer,
intent(in) :: fileunit
135 character(len=*),
parameter :: RoutineName =
"ufo_rttovonedvarcheck_GetEmisEigenVec"
136 integer :: eigversion
138 integer :: readstatus
139 character(len=max_string) :: message
145 read(fileunit, *, iostat = readstatus) eigversion, self % emis_eigen % Nchans, &
146 self % emis_eigen % NumEV
148 allocate (self % emis_eigen % Channels( self % emis_eigen % Nchans))
149 allocate (self % emis_eigen % Mean( self % emis_eigen % Nchans))
150 allocate (self % emis_eigen % PCmin( self % emis_eigen % NumEV))
151 allocate (self % emis_eigen % PCmax( self % emis_eigen % NumEV))
152 allocate (self % emis_eigen % PCguess( self % emis_eigen % NumEV))
153 allocate (self % emis_eigen % EV( self % emis_eigen % NumEV, self % emis_eigen % Nchans))
154 if (eigversion >= 2)
then
155 allocate (self % emis_eigen % EV_Inverse( self % emis_eigen % Nchans, self % emis_eigen % NumEV))
162 read (fileunit, *, iostat = readstatus) self % emis_eigen % Channels(:)
163 read (fileunit, *, iostat = readstatus) self % emis_eigen % Mean(:)
164 read (fileunit, *, iostat = readstatus) self % emis_eigen % PCmin(:)
165 read (fileunit, *, iostat = readstatus) self % emis_eigen % PCmax(:)
166 read (fileunit, *, iostat = readstatus) self % emis_eigen % PCguess(:)
167 do i = 1, self % emis_eigen % NumEV
168 read (fileunit, *, iostat = readstatus) self % emis_eigen % EV(i,:)
172 if (readstatus /= 0)
then
173 write(message,*) routinename, &
174 'Problem reading in emis eigenvectors - please check the file '
175 call abor1_ftn(message)
178 if (eigversion >= 2)
then
179 do i = 1, self % emis_eigen % Nchans
180 read (fileunit, *, iostat = readstatus) self % emis_eigen % EV_Inverse(i,:)
183 if (readstatus /= 0)
then
184 write(message,*) routinename, &
185 'Problem reading in inverse emis eigenvectors - please check the file '
186 call abor1_ftn(message)
190 write(*,
'(A,I0,A,I0,A)')
'Finished reading ',self % emis_eigen % NumEV, &
191 ' emissivity eigenvectors on ', &
192 self % emis_eigen % Nchans,
' channels.'
211 integer,
intent(in) :: fileunit
214 character(len=*),
parameter :: RoutineName =
"ufo_rttovonedvarcheck_GetEmisAtlas"
215 character(len=max_string) :: message
216 integer :: readstatus
224 read (fileunit, *, iostat = readstatus) self % emis_atlas % Nlat, &
225 self % emis_atlas % Nlon, &
226 self % emis_atlas % Npc, &
227 self % emis_atlas % gridstep
229 allocate (self % emis_atlas % EmisPC(self % emis_atlas % Nlon, &
230 self % emis_atlas % Nlat, &
231 self % emis_atlas % Npc))
237 do i = 1, self % emis_atlas % nlon
238 do j = 1, self % emis_atlas % nlat
239 read (fileunit,
'(12F10.6)', iostat = readstatus) self % emis_atlas % EmisPC(i,j,:)
244 if (readstatus /= 0)
then
245 write(message,*) routinename, &
246 'Problem reading in EmisAtlas - please check the file'
247 call abor1_ftn(message)
249 write (*,
'(A,I0,A)')
'Finished reading IR emissivity atlas with ', &
250 self % emis_atlas % Npc,
' principal components.'
271 character(len=*),
parameter :: routinename =
"ufo_rttovonedvarcheck_DeletePCEmis"
273 self % emis_eigen % NChans = 0
274 self % emis_eigen % NumEV = 0
275 if (
associated (self % emis_eigen % Channels))
deallocate (self % emis_eigen % Channels)
276 if (
associated (self % emis_eigen % Mean))
deallocate (self % emis_eigen % Mean)
277 if (
associated (self % emis_eigen % PCmin))
deallocate (self % emis_eigen % PCmin)
278 if (
associated (self % emis_eigen % PCmax))
deallocate (self % emis_eigen % PCmax)
279 if (
associated (self % emis_eigen % PCguess))
deallocate (self % emis_eigen % PCguess)
280 if (
associated (self % emis_eigen % EV))
deallocate (self % emis_eigen % EV)
281 if (
associated (self % emis_eigen % EV_Inverse))
deallocate (self % emis_eigen % EV_Inverse)
299 write(*,*)
"Printing contents of PC emiss"
300 write(*,*)
"emis_eigen % Channels = ",self % emis_eigen % Channels
323 integer,
intent(in) :: Channels(:)
324 real(kind_real),
intent(in) :: Emissivity(:)
325 real(kind_real),
intent(out) :: PC(:)
328 character(len=*),
parameter :: RoutineName =
"ufo_rttovonedvarcheck_EmisToPC"
329 real(kind_real) :: Temp_Emissivity(size(Emissivity))
331 character(len=max_string) :: message
335 if (
associated(self % emis_eigen % EV_Inverse))
then
338 temp_emissivity(:) = asin( 2.0_kind_real * emissivity(:) - 1.0_kind_real )
341 temp_emissivity(:) = temp_emissivity(:) - self % emis_eigen % Mean(channels(:))
344 pc(1:npc) = matmul(temp_emissivity(:), self % emis_eigen % EV_Inverse(channels(:),1:npc))
348 write(message, *) routinename, &
349 'Missing inverse eigenvector matrix - cannot convert emissivities to PCs'
350 call abor1_ftn(message)
376 integer,
intent(in) :: NumChans
377 integer,
intent(in) :: Channels(NumChans)
378 integer,
intent(in) :: NumPC
379 real(kind_real),
intent(in) :: PC(NumPC)
380 real(kind_real),
intent(out) :: Emissivity(NumChans)
383 character(len=*),
parameter :: RoutineName =
"ufo_rttovonedvarcheck_PCToEmis"
384 real(kind_real) :: BigEOF(NumChans,NumChans)
385 real(kind_real) :: BigPC(NumChans)
388 bigpc(:) = 0.0_kind_real
389 bigpc(1:numpc) = pc(:)
392 bigeof(:,:) = 0.0_kind_real
393 bigeof(1:numpc,:) = self % emis_eigen % EV(1:numpc,channels)
396 emissivity = matmul(bigpc, bigeof)
399 emissivity(:) = emissivity(:) + self % emis_eigen % Mean(channels)
402 emissivity(1:numchans) = 0.5_kind_real * (sin(emissivity(1:numchans)) + 1.0_kind_real)
427 integer,
intent(in) :: NumChans
428 integer,
intent(in) :: Channels(NumChans)
429 integer,
intent(in) :: NumPC
430 real(kind_real),
intent(in) :: Emissivity(NumChans)
431 real(kind_real),
intent(in) :: Emissivity_K(NumChans)
432 real(kind_real),
intent(out) :: PC_K(NumChans,NumPC)
435 character(len=*),
parameter :: RoutineName =
"ufo_rttovonedvarcheck_EmisKToPC"
436 real(kind_real) :: JEMatrix_element
439 do ichan = 1, numchans
443 jematrix_element = emissivity_k(ichan) * 0.5_kind_real* &
444 sqrt(1.0_kind_real - (1.0_kind_real - 2.0_kind_real * emissivity(ichan)) ** 2)
448 pc_k(ichan,1:numpc) = self % emis_eigen % EV(1:numpc,channels(ichan)) * jematrix_element
Fortran module constants used throughout the rttovonedvarcheck filter.
Fortran module which contains the methods for Infrared Principal Component Emissivity The science can...
subroutine ufo_rttovonedvarcheck_initpcemis(self, filepath, atlaspath)
Initialize PC emissivity object.
subroutine ufo_rttovonedvarcheck_deletepcemis(self)
Delete the PC emissivity object.
subroutine ufo_rttovonedvarcheck_getemisatlas(self, fileunit)
Read the emissivity eigen atlas from file.
subroutine ufo_rttovonedvarcheck_printpcemis(self)
Print information about the PC Emissivity object.
subroutine ufo_rttovonedvarcheck_pctoemis(self, NumChans, Channels, NumPC, PC, Emissivity)
Transform from principal components to emissivity spectrum.
subroutine ufo_rttovonedvarcheck_emisktopc(self, NumChans, Channels, NumPC, Emissivity, Emissivity_K, PC_K)
Transform from principal components to emissivity spectrum.
subroutine ufo_rttovonedvarcheck_getemiseigenvec(self, fileunit)
Read the emissivity eigen vector from file.
subroutine ufo_rttovonedvarcheck_emistopc(self, Channels, Emissivity, PC)
Convert from spectral emissivity to principal component weights. This is used to convert CAMEL emissi...
Fortran module with various useful routines.
integer function, public ufo_utils_iogetfreeunit()
Find a free file unit.