FV3 Bundle
CRTM_RTSolution_Define.f90
Go to the documentation of this file.
1 !
2 ! CRTM_RTSolution_Define
3 !
4 ! Module defining the CRTM RTSolution structure and containing routines
5 ! to manipulate it.
6 !
7 !
8 ! CREATION HISTORY:
9 ! Written by: Paul van Delst, 13-May-2004
10 ! paul.vandelst@noaa.gov
11 !
12 
14 
15 
16  ! ------------------
17  ! Environment set up
18  ! ------------------
19  ! Intrinsic modules
20  USE iso_fortran_env , ONLY: output_unit
21  ! Module use statements
22  USE type_kinds , ONLY: fp
25  OPERATOR(.equalto.), &
34  USE crtm_parameters , ONLY: strlen
35  ! Disable all implicit typing
36  IMPLICIT NONE
37 
38 
39  ! --------------------
40  ! Default visibilities
41  ! --------------------
42  ! Everything private by default
43  PRIVATE
44  ! Datatypes
45  PUBLIC :: crtm_rtsolution_type
46  ! Operators
47  PUBLIC :: OPERATOR(==)
48  PUBLIC :: OPERATOR(+)
49  PUBLIC :: OPERATOR(-)
50  ! Public procedures
52  PUBLIC :: crtm_rtsolution_destroy
53  PUBLIC :: crtm_rtsolution_create
54  PUBLIC :: crtm_rtsolution_zero
55  PUBLIC :: crtm_rtsolution_inspect
57  PUBLIC :: crtm_rtsolution_compare
60  PUBLIC :: crtm_rtsolution_readfile
62 
63 
64  ! ---------------------
65  ! Procedure overloading
66  ! ---------------------
67  INTERFACE OPERATOR(==)
68  MODULE PROCEDURE crtm_rtsolution_equal
69  END INTERFACE OPERATOR(==)
70 
71  INTERFACE OPERATOR(+)
72  MODULE PROCEDURE crtm_rtsolution_add
73  END INTERFACE OPERATOR(+)
74 
75  INTERFACE OPERATOR(-)
76  MODULE PROCEDURE crtm_rtsolution_subtract
77  END INTERFACE OPERATOR(-)
78 
79  INTERFACE OPERATOR(**)
80  MODULE PROCEDURE crtm_rtsolution_exponent
81  END INTERFACE OPERATOR(**)
82 
83  INTERFACE OPERATOR(/)
84  MODULE PROCEDURE crtm_rtsolution_normalise
85  END INTERFACE OPERATOR(/)
86 
87  INTERFACE sqrt
88  MODULE PROCEDURE crtm_rtsolution_sqrt
89  END INTERFACE sqrt
90 
92  MODULE PROCEDURE scalar_inspect
93  MODULE PROCEDURE rank2_inspect
94  END INTERFACE crtm_rtsolution_inspect
95 
96 
97  ! -----------------
98  ! Module parameters
99  ! -----------------
100  CHARACTER(*), PARAMETER :: module_version_id = &
101  '$Id: CRTM_RTSolution_Define.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
102  ! Literal constants
103  REAL(fp), PARAMETER :: zero = 0.0_fp
104  ! Message string length
105  INTEGER, PARAMETER :: ml = 256
106  ! File status on close after write error
107  CHARACTER(*), PARAMETER :: write_error_status = 'DELETE'
108 
109 
110  ! -------------------------------
111  ! RTSolution data type definition
112  ! -------------------------------
113  !:tdoc+:
115  ! Allocation indicator
116  LOGICAL :: is_allocated = .false.
117  ! Dimensions
118  INTEGER :: n_layers = 0 ! K
119  ! Sensor information
120  CHARACTER(STRLEN) :: sensor_id = ''
121  INTEGER :: wmo_satellite_id = invalid_wmo_satellite_id
122  INTEGER :: wmo_sensor_id = invalid_wmo_sensor_id
123  INTEGER :: sensor_channel = 0
124  ! RT algorithm information
125  CHARACTER(STRLEN*5) :: rt_algorithm_name = ''
126  ! Internal variables. Users do not need to worry about these.
127  LOGICAL :: scattering_flag = .true.
128  INTEGER :: n_full_streams = 0
129  INTEGER :: n_stokes = 0
130  ! Forward radiative transfer intermediate results for a single channel
131  ! These components are not defined when they are used as TL, AD
132  ! and K variables
133  REAL(fp) :: sod = zero ! Scattering Optical Depth
134  REAL(fp) :: surface_emissivity = zero
135  REAL(fp) :: surface_reflectivity = zero
136  REAL(fp) :: up_radiance = zero
137  REAL(fp) :: down_radiance = zero
138  REAL(fp) :: down_solar_radiance = zero
139  REAL(fp) :: surface_planck_radiance = zero
140  REAL(fp), ALLOCATABLE :: upwelling_overcast_radiance(:) ! K
141  REAL(fp), ALLOCATABLE :: upwelling_radiance(:) ! K
142  REAL(fp), ALLOCATABLE :: layer_optical_depth(:) ! K
143  ! Radiative transfer results for a single channel/node
144  REAL(fp) :: radiance = zero
145  REAL(fp) :: brightness_temperature = zero
146  END TYPE crtm_rtsolution_type
147  !:tdoc-:
148 
149 
150 CONTAINS
151 
152 
153 !##################################################################################
154 !##################################################################################
155 !## ##
156 !## ## PUBLIC MODULE ROUTINES ## ##
157 !## ##
158 !##################################################################################
159 !##################################################################################
160 
161 !--------------------------------------------------------------------------------
162 !:sdoc+:
163 !
164 ! NAME:
165 ! CRTM_RTSolution_Associated
166 !
167 ! PURPOSE:
168 ! Elemental function to test the status of the allocatable components
169 ! of a CRTM RTSolution object.
170 !
171 ! CALLING SEQUENCE:
172 ! Status = CRTM_RTSolution_Associated( RTSolution )
173 !
174 ! OBJECTS:
175 ! RTSolution: RTSolution structure which is to have its member's
176 ! status tested.
177 ! UNITS: N/A
178 ! TYPE: CRTM_RTSolution_type
179 ! DIMENSION: Scalar or any rank
180 ! ATTRIBUTES: INTENT(IN)
181 !
182 ! FUNCTION RESULT:
183 ! Status: The return value is a logical value indicating the
184 ! status of the RTSolution members.
185 ! .TRUE. - if the array components are allocated.
186 ! .FALSE. - if the array components are not allocated.
187 ! UNITS: N/A
188 ! TYPE: LOGICAL
189 ! DIMENSION: Same as input RTSolution argument
190 !
191 !:sdoc-:
192 !--------------------------------------------------------------------------------
193 
194  ELEMENTAL FUNCTION crtm_rtsolution_associated( RTSolution ) RESULT( Status )
195  TYPE(crtm_rtsolution_type), INTENT(IN) :: rtsolution
196  LOGICAL :: status
197  status = rtsolution%Is_Allocated
198  END FUNCTION crtm_rtsolution_associated
199 
200 
201 !--------------------------------------------------------------------------------
202 !:sdoc+:
203 !
204 ! NAME:
205 ! CRTM_RTSolution_Destroy
206 !
207 ! PURPOSE:
208 ! Elemental subroutine to re-initialize CRTM RTSolution objects.
209 !
210 ! CALLING SEQUENCE:
211 ! CALL CRTM_RTSolution_Destroy( RTSolution )
212 !
213 ! OBJECTS:
214 ! RTSolution: Re-initialized RTSolution structure.
215 ! UNITS: N/A
216 ! TYPE: CRTM_RTSolution_type
217 ! DIMENSION: Scalar OR any rank
218 ! ATTRIBUTES: INTENT(OUT)
219 !
220 !:sdoc-:
221 !--------------------------------------------------------------------------------
222 
223  ELEMENTAL SUBROUTINE crtm_rtsolution_destroy( RTSolution )
224  TYPE(crtm_rtsolution_type), INTENT(OUT) :: rtsolution
225  rtsolution%Is_Allocated = .false.
226  rtsolution%n_Layers = 0
227  END SUBROUTINE crtm_rtsolution_destroy
228 
229 
230 !--------------------------------------------------------------------------------
231 !:sdoc+:
232 !
233 ! NAME:
234 ! CRTM_RTSolution_Create
235 !
236 ! PURPOSE:
237 ! Elemental subroutine to create an instance of the CRTM RTSolution object.
238 !
239 ! CALLING SEQUENCE:
240 ! CALL CRTM_RTSolution_Create( RTSolution, n_Layers )
241 !
242 ! OBJECTS:
243 ! RTSolution: RTSolution structure.
244 ! UNITS: N/A
245 ! TYPE: CRTM_RTSolution_type
246 ! DIMENSION: Scalar or any rank
247 ! ATTRIBUTES: INTENT(OUT)
248 !
249 ! INPUTS:
250 ! n_Layers: Number of layers for which there is RTSolution data.
251 ! Must be > 0.
252 ! UNITS: N/A
253 ! TYPE: INTEGER
254 ! DIMENSION: Same as RTSolution object
255 ! ATTRIBUTES: INTENT(IN)
256 !
257 !:sdoc-:
258 !--------------------------------------------------------------------------------
259 
260  ELEMENTAL SUBROUTINE crtm_rtsolution_create( RTSolution, n_Layers )
261  ! Arguments
262  TYPE(crtm_rtsolution_type), INTENT(OUT) :: rtsolution
263  INTEGER, INTENT(IN) :: n_layers
264  ! Local variables
265  INTEGER :: alloc_stat
266 
267  ! Check input
268  IF ( n_layers < 1 ) RETURN
269 
270  ! Perform the allocation
271  ALLOCATE( rtsolution%Upwelling_Radiance(n_layers), &
272  rtsolution%Upwelling_Overcast_Radiance(n_layers), &
273  rtsolution%Layer_Optical_Depth(n_layers), &
274  stat = alloc_stat )
275  IF ( alloc_stat /= 0 ) RETURN
276 
277  ! Initialise
278  ! ...Dimensions
279  rtsolution%n_Layers = n_layers
280  ! ...Arrays
281  rtsolution%Upwelling_Radiance = zero
282  rtsolution%Upwelling_Overcast_Radiance = zero
283  rtsolution%Layer_Optical_Depth = zero
284 
285  ! Set allocation indicator
286  rtsolution%Is_Allocated = .true.
287 
288  END SUBROUTINE crtm_rtsolution_create
289 
290 
291 !--------------------------------------------------------------------------------
292 !:sdoc+:
293 !
294 ! NAME:
295 ! CRTM_RTSolution_Zero
296 !
297 ! PURPOSE:
298 ! Elemental subroutine to zero out the data components
299 ! in a CRTM RTSolution object.
300 !
301 ! CALLING SEQUENCE:
302 ! CALL CRTM_RTSolution_Zero( rts )
303 !
304 ! OUTPUTS:
305 ! rts: CRTM RTSolution structure in which the data components
306 ! are to be zeroed out.
307 ! UNITS: N/A
308 ! TYPE: CRTM_RTSolution_type
309 ! DIMENSION: Scalar or any rank
310 ! ATTRIBUTES: INTENT(IN OUT)
311 !
312 ! COMMENTS:
313 ! - The dimension components of the structure are *NOT* set to zero.
314 ! - The sensor infomration and RT algorithm components are
315 ! *NOT* reset in this routine.
316 !
317 !:sdoc-:
318 !--------------------------------------------------------------------------------
319 
320  ELEMENTAL SUBROUTINE crtm_rtsolution_zero( RTSolution )
321  TYPE(crtm_rtsolution_type), INTENT(IN OUT) :: rtsolution
322 
323  ! Zero out the scalar data components
324  rtsolution%SOD = zero
325  rtsolution%Surface_Emissivity = zero
326  rtsolution%Surface_Reflectivity = zero
327  rtsolution%Up_Radiance = zero
328  rtsolution%Down_Radiance = zero
329  rtsolution%Down_Solar_Radiance = zero
330  rtsolution%Surface_Planck_Radiance = zero
331  rtsolution%Radiance = zero
332  rtsolution%Brightness_Temperature = zero
333 
334  ! Zero out the array data components
335  IF ( crtm_rtsolution_associated(rtsolution) ) THEN
336  rtsolution%Upwelling_Radiance = zero
337  rtsolution%Upwelling_Overcast_Radiance = zero
338  rtsolution%Layer_Optical_Depth = zero
339  END IF
340 
341  END SUBROUTINE crtm_rtsolution_zero
342 
343 
344 !--------------------------------------------------------------------------------
345 !:sdoc+:
346 !
347 ! NAME:
348 ! CRTM_RTSolution_Inspect
349 !
350 ! PURPOSE:
351 ! Subroutine to print the contents of a CRTM RTSolution object to stdout.
352 !
353 ! CALLING SEQUENCE:
354 ! CALL CRTM_RTSolution_Inspect( RTSolution, Unit=unit )
355 !
356 ! INPUTS:
357 ! RTSolution: CRTM RTSolution object to display.
358 ! UNITS: N/A
359 ! TYPE: CRTM_RTSolution_type
360 ! DIMENSION: Scalar or Rank-2 (n_channels x n_profiles)
361 ! ATTRIBUTES: INTENT(IN)
362 !
363 ! OPTIONAL INPUTS:
364 ! Unit: Unit number for an already open file to which the output
365 ! will be written.
366 ! If the argument is specified and the file unit is not
367 ! connected, the output goes to stdout.
368 ! UNITS: N/A
369 ! TYPE: INTEGER
370 ! DIMENSION: Scalar
371 ! ATTRIBUTES: INTENT(IN), OPTIONAL
372 !
373 !:sdoc-:
374 !--------------------------------------------------------------------------------
375 
376  SUBROUTINE scalar_inspect( RTSolution, Unit )
377  ! Arguments
378  TYPE(CRTM_RTSolution_type), INTENT(IN) :: RTSolution
379  INTEGER, OPTIONAL, INTENT(IN) :: Unit
380  ! Local variables
381  INTEGER :: fid
382 
383  ! Setup
384  fid = output_unit
385  IF ( PRESENT(unit) ) THEN
386  IF ( file_open(unit) ) fid = unit
387  END IF
388 
389 
390  WRITE(fid,'(1x,"RTSolution OBJECT")')
391  ! Display components
392  WRITE(fid,'(3x,"Sensor Id : ",a )') trim(rtsolution%Sensor_ID)
393  WRITE(fid,'(3x,"WMO Satellite Id : ",i0)') rtsolution%WMO_Satellite_ID
394  WRITE(fid,'(3x,"WMO Sensor Id : ",i0)') rtsolution%WMO_Sensor_ID
395  WRITE(fid,'(3x,"Channel : ",i0)') rtsolution%Sensor_Channel
396  WRITE(fid,'(3x,"RT Algorithm Name : ",a )') rtsolution%RT_Algorithm_Name
397  WRITE(fid,'(3x,"Scattering Optical Depth : ",es13.6)') rtsolution%SOD
398  WRITE(fid,'(3x,"Surface Emissivity : ",es13.6)') rtsolution%Surface_Emissivity
399  WRITE(fid,'(3x,"Surface Reflectivity : ",es13.6)') rtsolution%Surface_Reflectivity
400  WRITE(fid,'(3x,"Up Radiance : ",es13.6)') rtsolution%Up_Radiance
401  WRITE(fid,'(3x,"Down Radiance : ",es13.6)') rtsolution%Down_Radiance
402  WRITE(fid,'(3x,"Down Solar Radiance : ",es13.6)') rtsolution%Down_Solar_Radiance
403  WRITE(fid,'(3x,"Surface Planck Radiance : ",es13.6)') rtsolution%Surface_Planck_Radiance
404  WRITE(fid,'(3x,"Radiance : ",es13.6)') rtsolution%Radiance
405  WRITE(fid,'(3x,"Brightness Temperature : ",es13.6)') rtsolution%Brightness_Temperature
406  IF ( .NOT. crtm_rtsolution_associated(rtsolution) ) RETURN
407  WRITE(fid,'(3x,"n_Layers : ",i0)') rtsolution%n_Layers
408  WRITE(fid,'(3x,"Upwelling Radiance :")')
409  WRITE(fid,'(5(1x,es13.6,:))') rtsolution%Upwelling_Radiance
410  WRITE(fid,'(3x,"Layer Optical Depth :")')
411  WRITE(fid,'(5(1x,es13.6,:))') rtsolution%Layer_Optical_Depth
412  END SUBROUTINE scalar_inspect
413 
414 
415  SUBROUTINE rank2_inspect( RTSolution, Unit )
416  TYPE(CRTM_RTSolution_type), INTENT(IN) :: RTSolution(:,:)
417  INTEGER, OPTIONAL, INTENT(IN) :: Unit
418  INTEGER :: fid
419  INTEGER :: i, n_channels
420  INTEGER :: j, n_profiles
421 
422  fid = output_unit
423  IF ( PRESENT(unit) ) THEN
424  IF ( file_open(unit) ) fid = unit
425  END IF
426 
427  n_channels = SIZE(rtsolution,1)
428  n_profiles = SIZE(rtsolution,2)
429  DO j = 1, n_profiles
430  DO i = 1, n_channels
431  WRITE(fid, fmt='(1x,"PROFILE INDEX:",i0,", CHANNEL INDEX:",i0," - ")', advance='NO') j,i
432  CALL scalar_inspect(rtsolution(i,j), unit=unit)
433  END DO
434  END DO
435  END SUBROUTINE rank2_inspect
436 
437 
438 
439 !--------------------------------------------------------------------------------
440 !:sdoc+:
441 !
442 ! NAME:
443 ! CRTM_RTSolution_DefineVersion
444 !
445 ! PURPOSE:
446 ! Subroutine to return the module version information.
447 !
448 ! CALLING SEQUENCE:
449 ! CALL CRTM_RTSolution_DefineVersion( Id )
450 !
451 ! OUTPUTS:
452 ! Id: Character string containing the version Id information
453 ! for the module.
454 ! UNITS: N/A
455 ! TYPE: CHARACTER(*)
456 ! DIMENSION: Scalar
457 ! ATTRIBUTES: INTENT(OUT)
458 !
459 !:sdoc-:
460 !--------------------------------------------------------------------------------
461 
462  SUBROUTINE crtm_rtsolution_defineversion( Id )
463  CHARACTER(*), INTENT(OUT) :: id
464  id = module_version_id
465  END SUBROUTINE crtm_rtsolution_defineversion
466 
467 
468 !------------------------------------------------------------------------------
469 !:sdoc+:
470 ! NAME:
471 ! CRTM_RTSolution_Compare
472 !
473 ! PURPOSE:
474 ! Elemental function to compare two CRTM_RTSolution objects to within
475 ! a user specified number of significant figures.
476 !
477 ! CALLING SEQUENCE:
478 ! is_comparable = CRTM_RTSolution_Compare( x, y, n_SigFig=n_SigFig )
479 !
480 ! OBJECTS:
481 ! x, y: Two CRTM RTSolution objects to be compared.
482 ! UNITS: N/A
483 ! TYPE: CRTM_RTSolution_type
484 ! DIMENSION: Scalar or any rank
485 ! ATTRIBUTES: INTENT(IN)
486 !
487 ! OPTIONAL INPUTS:
488 ! n_SigFig: Number of significant figure to compare floating point
489 ! components.
490 ! UNITS: N/A
491 ! TYPE: INTEGER
492 ! DIMENSION: Conformable with inputs
493 ! ATTRIBUTES: INTENT(IN), OPTIONAL
494 !
495 ! FUNCTION RESULT:
496 ! is_comparable: Logical value indicating whether the inputs are
497 ! comparable.
498 ! UNITS: N/A
499 ! TYPE: LOGICAL
500 ! DIMENSION: Same as inputs.
501 !:sdoc-:
502 !------------------------------------------------------------------------------
503 
504  ELEMENTAL FUNCTION crtm_rtsolution_compare( &
505  x, &
506  y, &
507  n_SigFig ) &
508  result( is_comparable )
509  TYPE(crtm_rtsolution_type), INTENT(IN) :: x, y
510  INTEGER, OPTIONAL, INTENT(IN) :: n_sigfig
511  LOGICAL :: is_comparable
512  ! Variables
513  INTEGER :: n
514 
515  ! Set up
516  is_comparable = .false.
517  IF ( PRESENT(n_sigfig) ) THEN
518  n = abs(n_sigfig)
519  ELSE
520  n = default_n_sigfig
521  END IF
522 
523  ! Check the structure association status
524  IF ( crtm_rtsolution_associated(x) .NEQV. crtm_rtsolution_associated(y) ) RETURN
525 
526  ! Check the sensor information
527  IF ( (x%Sensor_ID /= y%Sensor_ID ) .OR. &
528  (x%WMO_Satellite_ID /= y%WMO_Satellite_ID) .OR. &
529  (x%WMO_Sensor_ID /= y%WMO_Sensor_ID ) .OR. &
530  (x%Sensor_Channel /= y%Sensor_Channel ) ) RETURN
531 
532  ! Check the RT algorithm name
533  IF ( x%RT_Algorithm_Name /= y%RT_Algorithm_Name ) RETURN
534 
535  ! Check the scalar components
536  IF ( .NOT. compares_within_tolerance(x%SOD , y%SOD , n) .OR. &
537  .NOT. compares_within_tolerance(x%Surface_Emissivity , y%Surface_Emissivity , n) .OR. &
538  .NOT. compares_within_tolerance(x%Surface_Reflectivity , y%Surface_Reflectivity , n) .OR. &
539  .NOT. compares_within_tolerance(x%Up_Radiance , y%Up_Radiance , n) .OR. &
540  .NOT. compares_within_tolerance(x%Down_Radiance , y%Down_Radiance , n) .OR. &
541  .NOT. compares_within_tolerance(x%Down_Solar_Radiance , y%Down_Solar_Radiance , n) .OR. &
542  .NOT. compares_within_tolerance(x%Surface_Planck_Radiance, y%Surface_Planck_Radiance, n) .OR. &
543  .NOT. compares_within_tolerance(x%Radiance , y%Radiance , n) .OR. &
544  .NOT. compares_within_tolerance(x%Brightness_Temperature , y%Brightness_Temperature , n) ) RETURN
545 
546  ! Check the array components
548  IF ( (.NOT. all(compares_within_tolerance(x%Upwelling_Overcast_Radiance, y%Upwelling_Overcast_Radiance, n))) .OR. &
549  (.NOT. all(compares_within_tolerance(x%Upwelling_Radiance , y%Upwelling_Radiance , n))) .OR. &
550  (.NOT. all(compares_within_tolerance(x%Layer_Optical_Depth , y%Layer_Optical_Depth , n))) ) RETURN
551  END IF
552 
553  ! If we get here, the structures are comparable
554  is_comparable = .true.
555 
556  END FUNCTION crtm_rtsolution_compare
557 
558 
559 !--------------------------------------------------------------------------------
560 !:sdoc+:
561 !
562 ! NAME:
563 ! CRTM_RTSolution_Statistics
564 !
565 ! PURPOSE:
566 ! Function to compute the statistics of an array of CRTM RTSolution objects.
567 !
568 ! CALLING SEQUENCE:
569 ! Error_Status = CRTM_RTSolution_Statistics( rts, rts_stats )
570 !
571 ! INPUTS:
572 ! rts: RTSolution object array for which statistics are required.
573 ! UNITS: N/A
574 ! TYPE: CRTM_RTSolution_type
575 ! DIMENSION: Rank-2 (n_channels x n_profiles)
576 ! ATTRIBUTES: INTENT(IN)
577 !
578 ! OUTPUTS:
579 ! rts_stats: Allocatable RTSolution object array containing the statistics
580 ! for each channel.
581 ! rts_stats(:,1) contains the profile average
582 ! rts_stats(:,2) contains the profile standard deviation
583 ! UNITS: N/A
584 ! TYPE: CRTM_RTSolution_type
585 ! DIMENSION: Rank-2 (n_channels x 2)
586 ! ATTRIBUTES: INTENT(IN), ALLOCATABLE
587 !
588 ! FUNCTION RESULT:
589 ! Error_Status: The return value is an integer defining the error status.
590 ! The error codes are defined in the Message_Handler module.
591 ! If == SUCCESS, the file write was successful
592 ! == FAILURE, an unrecoverable error occurred.
593 ! UNITS: N/A
594 ! TYPE: INTEGER
595 ! DIMENSION: Scalar
596 !:sdoc-:
597 !--------------------------------------------------------------------------------
598 
599  FUNCTION crtm_rtsolution_statistics(rts, rts_stats) RESULT( err_stat )
600  ! Arguments
601  TYPE(crtm_rtsolution_type), INTENT(IN) :: rts(:,:)
602  TYPE(crtm_rtsolution_type), ALLOCATABLE, INTENT(OUT) :: rts_stats(:,:)
603  ! Function result
604  INTEGER :: err_stat
605  ! Function parameters
606  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_RTSolution_Statistics'
607  ! Function variables
608  CHARACTER(ML) :: err_msg
609  CHARACTER(ML) :: alloc_msg
610  INTEGER :: alloc_stat
611  INTEGER :: n_channels, l
612  INTEGER :: n_profiles, m
613  REAL(fp) :: factor
614 
615  ! Setup
616  err_stat = success
617  n_channels = SIZE(rts, dim=1)
618  n_profiles = SIZE(rts, dim=2)
619  factor = REAL(n_profiles,fp)
620 
621 
622  ! Allocate the output stats object array
623  ALLOCATE( rts_stats(n_channels, 2), &
624  stat = alloc_stat, errmsg = alloc_msg )
625  IF ( alloc_stat /= 0 ) THEN
626  err_msg = 'Error allocating output RTSolution structure - '//trim(alloc_msg)
627  err_stat = failure
628  CALL display_message( routine_name, err_msg, err_stat ); RETURN
629  END IF
630  rts_stats(:,1) = rts(:,1)
631  rts_stats(:,2) = rts(:,1)
632  CALL crtm_rtsolution_zero(rts_stats)
633 
634 
635  ! Compute the average
636  DO m = 1, n_profiles
637  DO l = 1, n_channels
638  rts_stats(l,1) = rts_stats(l,1) + rts(l,m)
639  END DO
640  END DO
641  rts_stats(:,1) = rts_stats(:,1)/factor
642 
643 
644  ! Compute the standard deviation
645  DO m = 1, n_profiles
646  DO l = 1, n_channels
647  rts_stats(l,2) = rts_stats(l,2) + (rts(l,m) - rts_stats(l,1))**2
648  END DO
649  END DO
650  rts_stats(:,2) = sqrt(rts_stats(:,2)/factor)
651 
652 
653  ! Replace the algorithm identifier
654  rts_stats(:,1)%RT_Algorithm_Name = 'Object average'
655  rts_stats(:,2)%RT_Algorithm_Name = 'Object standard deviation'
656 
657  END FUNCTION crtm_rtsolution_statistics
658 
659 
660 !------------------------------------------------------------------------------
661 !:sdoc+:
662 !
663 ! NAME:
664 ! CRTM_RTSolution_InquireFile
665 !
666 ! PURPOSE:
667 ! Function to inquire CRTM RTSolution object files.
668 !
669 ! CALLING SEQUENCE:
670 ! Error_Status = CRTM_RTSolution_InquireFile( Filename , &
671 ! n_Channels = n_Channels, &
672 ! n_Profiles = n_Profiles )
673 !
674 ! INPUTS:
675 ! Filename: Character string specifying the name of a
676 ! CRTM RTSolution data file to read.
677 ! UNITS: N/A
678 ! TYPE: CHARACTER(*)
679 ! DIMENSION: Scalar
680 ! ATTRIBUTES: INTENT(IN)
681 !
682 ! OPTIONAL OUTPUTS:
683 ! n_Channels: The number of spectral channels for which there is
684 ! data in the file.
685 ! UNITS: N/A
686 ! TYPE: INTEGER
687 ! DIMENSION: Scalar
688 ! ATTRIBUTES: OPTIONAL, INTENT(OUT)
689 !
690 ! n_Profiles: The number of profiles in the data file.
691 ! UNITS: N/A
692 ! TYPE: INTEGER
693 ! DIMENSION: Scalar
694 ! ATTRIBUTES: OPTIONAL, INTENT(OUT)
695 !
696 ! FUNCTION RESULT:
697 ! Error_Status: The return value is an integer defining the error status.
698 ! The error codes are defined in the Message_Handler module.
699 ! If == SUCCESS, the file inquire was successful
700 ! == FAILURE, an unrecoverable error occurred.
701 ! UNITS: N/A
702 ! TYPE: INTEGER
703 ! DIMENSION: Scalar
704 !
705 !:sdoc-:
706 !------------------------------------------------------------------------------
707 
708  FUNCTION crtm_rtsolution_inquirefile( &
709  Filename , & ! Input
710  n_Channels , & ! Optional output
711  n_Profiles ) & ! Optional output
712  result( err_stat )
713  ! Arguments
714  CHARACTER(*), INTENT(IN) :: filename
715  INTEGER , OPTIONAL, INTENT(OUT) :: n_channels
716  INTEGER , OPTIONAL, INTENT(OUT) :: n_profiles
717  ! Function result
718  INTEGER :: err_stat
719  ! Function parameters
720  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_RTSolution_InquireFile'
721  ! Function variables
722  CHARACTER(ML) :: msg
723  CHARACTER(ML) :: io_msg
724  INTEGER :: io_stat
725  INTEGER :: fid
726  INTEGER :: l, m
727 
728  ! Set up
729  err_stat = success
730  ! Check that the file exists
731  IF ( .NOT. file_exists( trim(filename) ) ) THEN
732  msg = 'File '//trim(filename)//' not found.'
733  CALL inquire_cleanup(); RETURN
734  END IF
735 
736  ! Open the file
737  err_stat = open_binary_file( filename, fid )
738  IF ( err_stat /= success ) THEN
739  msg = 'Error opening '//trim(filename)
740  CALL inquire_cleanup(); RETURN
741  END IF
742 
743  ! Read the number of channels,profiles
744  READ( fid,iostat=io_stat,iomsg=io_msg ) l, m
745  IF ( io_stat /= 0 ) THEN
746  msg = 'Error reading dimensions from '//trim(filename)//' - '//trim(io_msg)
747  CALL inquire_cleanup(); RETURN
748  END IF
749 
750  ! Close the file
751  CLOSE( fid,iostat=io_stat,iomsg=io_msg )
752  IF ( io_stat /= 0 ) THEN
753  msg = 'Error closing '//trim(filename)//' - '//trim(io_msg)
754  CALL inquire_cleanup(); RETURN
755  END IF
756 
757  ! Set the return arguments
758  IF ( PRESENT(n_channels) ) n_channels = l
759  IF ( PRESENT(n_profiles) ) n_profiles = m
760 
761  CONTAINS
762 
763  SUBROUTINE inquire_cleanup()
764  IF ( file_open( filename ) ) THEN
765  CLOSE( fid,iostat=io_stat,iomsg=io_msg )
766  IF ( io_stat /= success ) &
767  msg = trim(msg)//'; Error closing input file during error cleanup - '//trim(io_msg)
768  END IF
769  err_stat = failure
770  CALL display_message( routine_name, msg, err_stat )
771  END SUBROUTINE inquire_cleanup
772 
773  END FUNCTION crtm_rtsolution_inquirefile
774 
775 
776 !------------------------------------------------------------------------------
777 !:sdoc+:
778 !
779 ! NAME:
780 ! CRTM_RTSolution_ReadFile
781 !
782 ! PURPOSE:
783 ! Function to read CRTM RTSolution object files.
784 !
785 ! CALLING SEQUENCE:
786 ! Error_Status = CRTM_RTSolution_ReadFile( Filename , &
787 ! RTSolution , &
788 ! Quiet = Quiet , &
789 ! n_Channels = n_Channels , &
790 ! n_Profiles = n_Profiles , &
791 !
792 ! INPUTS:
793 ! Filename: Character string specifying the name of an
794 ! RTSolution format data file to read.
795 ! UNITS: N/A
796 ! TYPE: CHARACTER(*)
797 ! DIMENSION: Scalar
798 ! ATTRIBUTES: INTENT(IN)
799 !
800 ! OUTPUTS:
801 ! RTSolution: CRTM RTSolution object array containing the RTSolution
802 ! data.
803 ! UNITS: N/A
804 ! TYPE: CRTM_RTSolution_type
805 ! DIMENSION: Rank-2 (n_Channels x n_Profiles)
806 ! ATTRIBUTES: INTENT(OUT)
807 !
808 ! OPTIONAL INPUTS:
809 ! Quiet: Set this logical argument to suppress INFORMATION
810 ! messages being printed to stdout
811 ! If == .FALSE., INFORMATION messages are OUTPUT [DEFAULT].
812 ! == .TRUE., INFORMATION messages are SUPPRESSED.
813 ! If not specified, default is .FALSE.
814 ! UNITS: N/A
815 ! TYPE: LOGICAL
816 ! DIMENSION: Scalar
817 ! ATTRIBUTES: INTENT(IN), OPTIONAL
818 !
819 ! OPTIONAL OUTPUTS:
820 ! n_Channels: The number of channels for which data was read.
821 ! UNITS: N/A
822 ! TYPE: INTEGER
823 ! DIMENSION: Scalar
824 ! ATTRIBUTES: OPTIONAL, INTENT(OUT)
825 !
826 ! n_Profiles: The number of profiles for which data was read.
827 ! UNITS: N/A
828 ! TYPE: INTEGER
829 ! DIMENSION: Scalar
830 ! ATTRIBUTES: OPTIONAL, INTENT(OUT)
831 !
832 !
833 ! FUNCTION RESULT:
834 ! Error_Status: The return value is an integer defining the error status.
835 ! The error codes are defined in the Message_Handler module.
836 ! If == SUCCESS, the file read was successful
837 ! == FAILURE, an unrecoverable error occurred.
838 ! UNITS: N/A
839 ! TYPE: INTEGER
840 ! DIMENSION: Scalar
841 !
842 !:sdoc-:
843 !------------------------------------------------------------------------------
844 
845  FUNCTION crtm_rtsolution_readfile( &
846  Filename , & ! Input
847  RTSolution , & ! Output
848  Quiet , & ! Optional input
849  n_Channels , & ! Optional output
850  n_Profiles , & ! Optional output
851  Old_Version, & ! Optional input (Allow reading of previous version files)
852  debug ) & ! Optional input (Debug output control)
853  result( err_stat )
854  ! Arguments
855  CHARACTER(*), INTENT(IN) :: filename
856  TYPE(crtm_rtsolution_type), INTENT(OUT) :: rtsolution(:,:)
857  LOGICAL, OPTIONAL, INTENT(IN) :: quiet
858  INTEGER, OPTIONAL, INTENT(OUT) :: n_channels
859  INTEGER, OPTIONAL, INTENT(OUT) :: n_profiles
860  LOGICAL, OPTIONAL, INTENT(IN) :: old_version
861  LOGICAL, OPTIONAL, INTENT(IN) :: debug
862  ! Function result
863  INTEGER :: err_stat
864  ! Function parameters
865  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_RTSolution_ReadFile'
866  ! Function variables
867  CHARACTER(ML) :: msg
868  CHARACTER(ML) :: io_msg
869  INTEGER :: io_stat
870  LOGICAL :: noisy
871  INTEGER :: fid
872  INTEGER :: l, n_file_channels, n_input_channels
873  INTEGER :: m, n_file_profiles, n_input_profiles
874 
875 
876  ! Set up
877  err_stat = success
878  ! ...Check Quiet argument
879  noisy = .true.
880  IF ( PRESENT(quiet) ) noisy = .NOT. quiet
881  ! ...Override Quiet settings if debug set.
882  IF ( PRESENT(debug) ) noisy = debug
883 
884 
885  ! Open the file
886  err_stat = open_binary_file( filename, fid )
887  IF ( err_stat /= success ) THEN
888  msg = 'Error opening '//trim(filename)
889  CALL read_cleanup(); RETURN
890  END IF
891 
892 
893  ! Read the dimensions
894  READ( fid,iostat=io_stat,iomsg=io_msg ) n_file_channels, n_file_profiles
895  IF ( io_stat /= 0 ) THEN
896  msg = 'Error reading dimensions from '//trim(filename)//' - '//trim(io_msg)
897  CALL read_cleanup(); RETURN
898  END IF
899  ! ...Check if n_Channels in file is > size of output array
900  n_input_channels = SIZE(rtsolution,dim=1)
901  IF ( n_file_channels > n_input_channels ) THEN
902  WRITE( msg,'("Number of channels, ",i0," > size of the output RTSolution", &
903  &" array dimension, ",i0,". Only the first ",i0, &
904  &" channels will be read.")' ) &
905  n_file_channels, n_input_channels, n_input_channels
906  CALL display_message( routine_name, msg, warning )
907  END IF
908  n_input_channels = min(n_input_channels, n_file_channels)
909  ! ...Check if n_Profiles in file is > size of output array
910  n_input_profiles = SIZE(rtsolution,dim=2)
911  IF ( n_file_profiles > n_input_profiles ) THEN
912  WRITE( msg,'( "Number of profiles, ",i0," > size of the output RTSolution", &
913  &" array dimension, ",i0,". Only the first ",i0, &
914  &" profiles will be read.")' ) &
915  n_file_profiles, n_input_profiles, n_input_profiles
916  CALL display_message( routine_name, msg, warning )
917  END IF
918  n_input_profiles = min(n_input_profiles, n_file_profiles)
919 
920 
921  ! Loop over all the profiles and channels
922  profile_loop: DO m = 1, n_input_profiles
923  channel_loop: DO l = 1, n_input_channels
924  err_stat = read_record( fid, rtsolution(l,m), old_version=old_version )
925  IF ( err_stat /= success ) THEN
926  WRITE( msg,'("Error reading RTSolution element (",i0,",",i0,") from ",a)' ) &
927  l, m, trim(filename)
928  CALL read_cleanup(); RETURN
929  END IF
930  END DO channel_loop
931  END DO profile_loop
932 
933 
934  ! Close the file
935  CLOSE( fid,iostat=io_stat,iomsg=io_msg )
936  IF ( io_stat /= 0 ) THEN
937  msg = 'Error closing '//trim(filename)//' - '//trim(io_msg)
938  CALL read_cleanup(); RETURN
939  END IF
940 
941 
942  ! Set the return values
943  IF ( PRESENT(n_channels) ) n_channels = n_input_channels
944  IF ( PRESENT(n_profiles) ) n_profiles = n_input_profiles
945 
946 
947  ! Output an info message
948  IF ( noisy ) THEN
949  WRITE( msg,'("Number of channels and profiles read from ",a,": ",i0,1x,i0)' ) &
950  trim(filename), n_input_channels, n_input_profiles
951  CALL display_message( routine_name, msg, information )
952  END IF
953 
954  CONTAINS
955 
956  SUBROUTINE read_cleanup()
957  IF ( file_open( filename ) ) THEN
958  CLOSE( fid,iostat=io_stat,iomsg=io_msg )
959  IF ( io_stat /= 0 ) &
960  msg = trim(msg)//'; Error closing input file during error cleanup - '//trim(io_msg)
961  END IF
962  CALL crtm_rtsolution_destroy( rtsolution )
963  err_stat = failure
964  CALL display_message( routine_name, msg, err_stat )
965  END SUBROUTINE read_cleanup
966 
967  END FUNCTION crtm_rtsolution_readfile
968 
969 
970 !------------------------------------------------------------------------------
971 !:sdoc+:
972 !
973 ! NAME:
974 ! CRTM_RTSolution_WriteFile
975 !
976 ! PURPOSE:
977 ! Function to write CRTM RTSolution object files.
978 !
979 ! CALLING SEQUENCE:
980 ! Error_Status = CRTM_RTSolution_WriteFile( Filename , &
981 ! RTSolution , &
982 ! Quiet = Quiet )
983 !
984 ! INPUTS:
985 ! Filename: Character string specifying the name of the
986 ! RTSolution format data file to write.
987 ! UNITS: N/A
988 ! TYPE: CHARACTER(*)
989 ! DIMENSION: Scalar
990 ! ATTRIBUTES: INTENT(IN)
991 !
992 ! RTSolution: CRTM RTSolution object array containing the RTSolution
993 ! data.
994 ! UNITS: N/A
995 ! TYPE: CRTM_RTSolution_type
996 ! DIMENSION: Rank-2 (n_Channels x n_Profiles)
997 ! ATTRIBUTES: INTENT(IN)
998 !
999 ! OPTIONAL INPUTS:
1000 ! Quiet: Set this logical argument to suppress INFORMATION
1001 ! messages being printed to stdout
1002 ! If == .FALSE., INFORMATION messages are OUTPUT [DEFAULT].
1003 ! == .TRUE., INFORMATION messages are SUPPRESSED.
1004 ! If not specified, default is .FALSE.
1005 ! UNITS: N/A
1006 ! TYPE: LOGICAL
1007 ! DIMENSION: Scalar
1008 ! ATTRIBUTES: INTENT(IN), OPTIONAL
1009 !
1010 ! FUNCTION RESULT:
1011 ! Error_Status: The return value is an integer defining the error status.
1012 ! The error codes are defined in the Message_Handler module.
1013 ! If == SUCCESS, the file write was successful
1014 ! == FAILURE, an unrecoverable error occurred.
1015 ! UNITS: N/A
1016 ! TYPE: INTEGER
1017 ! DIMENSION: Scalar
1018 !
1019 ! SIDE EFFECTS:
1020 ! - If the output file already exists, it is overwritten.
1021 ! - If an error occurs during *writing*, the output file is deleted before
1022 ! returning to the calling routine.
1023 !
1024 !:sdoc-:
1025 !------------------------------------------------------------------------------
1026 
1027  FUNCTION crtm_rtsolution_writefile( &
1028  Filename , & ! Input
1029  RTSolution , & ! Input
1030  Quiet , & ! Optional input
1031  Debug ) & ! Optional input (Debug output control)
1032  result( err_stat )
1033  ! Arguments
1034  CHARACTER(*), INTENT(IN) :: filename
1035  TYPE(crtm_rtsolution_type), INTENT(IN) :: rtsolution(:,:)
1036  LOGICAL, OPTIONAL, INTENT(IN) :: quiet
1037  LOGICAL, OPTIONAL, INTENT(IN) :: debug
1038  ! Function result
1039  INTEGER :: err_stat
1040  ! Function parameters
1041  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_RTSolution_WriteFile'
1042  ! Function variables
1043  CHARACTER(ML) :: msg
1044  CHARACTER(ML) :: io_msg
1045  INTEGER :: io_stat
1046  LOGICAL :: noisy
1047  INTEGER :: fid
1048  INTEGER :: l, n_output_channels
1049  INTEGER :: m, n_output_profiles
1050 
1051  ! Set up
1052  err_stat = success
1053  ! ...Check Quiet argument
1054  noisy = .true.
1055  IF ( PRESENT(quiet) ) noisy = .NOT. quiet
1056  ! ...Override Quiet settings if debug set.
1057  IF ( PRESENT(debug) ) noisy = debug
1058  n_output_channels = SIZE(rtsolution,dim=1)
1059  n_output_profiles = SIZE(rtsolution,dim=2)
1060 
1061 
1062  ! Open the file
1063  err_stat = open_binary_file( filename, fid, for_output = .true. )
1064  IF ( err_stat /= success ) THEN
1065  msg = 'Error opening '//trim(filename)
1066  CALL write_cleanup(); RETURN
1067  END IF
1068 
1069 
1070  ! Write the dimensions
1071  WRITE( fid,iostat=io_stat,iomsg=io_msg ) n_output_channels, n_output_profiles
1072  IF ( io_stat /= 0 ) THEN
1073  msg = 'Error writing dimensions to '//trim(filename)//' - '//trim(io_msg)
1074  CALL write_cleanup(); RETURN
1075  END IF
1076 
1077 
1078  ! Write the data
1079  profile_loop: DO m = 1, n_output_profiles
1080  channel_loop: DO l = 1, n_output_channels
1081  err_stat = write_record( fid, rtsolution(l,m) )
1082  IF ( err_stat /= success ) THEN
1083  WRITE( msg,'("Error writing RTSolution element (",i0,",",i0,") to ",a)' ) &
1084  l, m, trim(filename)
1085  CALL write_cleanup(); RETURN
1086  END IF
1087  END DO channel_loop
1088  END DO profile_loop
1089 
1090 
1091  ! Close the file (if error, no delete)
1092  CLOSE( fid,status='KEEP',iostat=io_stat,iomsg=io_msg )
1093  IF ( io_stat /= 0 ) THEN
1094  msg = 'Error closing '//trim(filename)//' - '//trim(io_msg)
1095  CALL write_cleanup(); RETURN
1096  END IF
1097 
1098 
1099  ! Output an info message
1100  IF ( noisy ) THEN
1101  WRITE( msg,'("Number of channels and profiles written to ",a,": ",i0,1x,i0 )' ) &
1102  trim(filename), n_output_channels, n_output_profiles
1103  CALL display_message( routine_name, msg, information )
1104  END IF
1105 
1106  CONTAINS
1107 
1108  SUBROUTINE write_cleanup()
1109  IF ( file_open( filename ) ) THEN
1110  CLOSE( fid,status=write_error_status,iostat=io_stat,iomsg=io_msg )
1111  IF ( io_stat /= 0 ) &
1112  msg = trim(msg)//'; Error deleting output file during error cleanup - '//trim(io_msg)
1113  END IF
1114  err_stat = failure
1115  CALL display_message( routine_name, msg, err_stat )
1116  END SUBROUTINE write_cleanup
1117 
1118  END FUNCTION crtm_rtsolution_writefile
1119 
1120 
1121 
1122 !##################################################################################
1123 !##################################################################################
1124 !## ##
1125 !## ## PRIVATE MODULE ROUTINES ## ##
1126 !## ##
1127 !##################################################################################
1128 !##################################################################################
1129 
1130 !------------------------------------------------------------------------------
1131 !
1132 ! NAME:
1133 ! CRTM_RTSolution_Equal
1134 !
1135 ! PURPOSE:
1136 ! Elemental function to test the equality of two CRTM_RTSolution objects.
1137 ! Used in OPERATOR(==) interface block.
1138 !
1139 ! CALLING SEQUENCE:
1140 ! is_equal = CRTM_RTSolution_Equal( x, y )
1141 !
1142 ! or
1143 !
1144 ! IF ( x == y ) THEN
1145 ! ...
1146 ! END IF
1147 !
1148 ! OBJECTS:
1149 ! x, y: Two CRTM RTSolution objects to be compared.
1150 ! UNITS: N/A
1151 ! TYPE: CRTM_RTSolution_type
1152 ! DIMENSION: Scalar or any rank
1153 ! ATTRIBUTES: INTENT(IN)
1154 !
1155 ! FUNCTION RESULT:
1156 ! is_equal: Logical value indicating whether the inputs are equal.
1157 ! UNITS: N/A
1158 ! TYPE: LOGICAL
1159 ! DIMENSION: Same as inputs.
1160 !
1161 !------------------------------------------------------------------------------
1162 
1163  ELEMENTAL FUNCTION crtm_rtsolution_equal( x, y ) RESULT( is_equal )
1164  TYPE(crtm_rtsolution_type) , INTENT(IN) :: x, y
1165  LOGICAL :: is_equal
1166 
1167  ! Setup
1168  is_equal = .false.
1169 
1170  ! Check the structure association status
1171  IF ( crtm_rtsolution_associated(x) .NEQV. crtm_rtsolution_associated(y) ) RETURN
1172 
1173  ! Check scalars
1174  IF ( (x%n_Layers == y%n_Layers) .AND. &
1175  (x%Sensor_ID == y%Sensor_ID ) .AND. &
1176  (x%WMO_Satellite_ID == y%WMO_Satellite_ID ) .AND. &
1177  (x%WMO_Sensor_ID == y%WMO_Sensor_ID ) .AND. &
1178  (x%Sensor_Channel == y%Sensor_Channel ) .AND. &
1179  (x%RT_Algorithm_Name == y%RT_Algorithm_Name) .AND. &
1180  (x%SOD .equalto. y%SOD ) .AND. &
1181  (x%Surface_Emissivity .equalto. y%Surface_Emissivity ) .AND. &
1182  (x%Surface_Reflectivity .equalto. y%Surface_Reflectivity ) .AND. &
1183  (x%Up_Radiance .equalto. y%Up_Radiance ) .AND. &
1184  (x%Down_Radiance .equalto. y%Down_Radiance ) .AND. &
1185  (x%Down_Solar_Radiance .equalto. y%Down_Solar_Radiance ) .AND. &
1186  (x%Surface_Planck_Radiance .equalto. y%Surface_Planck_Radiance) .AND. &
1187  (x%Radiance .equalto. y%Radiance ) .AND. &
1188  (x%Brightness_Temperature .equalto. y%Brightness_Temperature ) ) &
1189  is_equal = .true.
1190 
1191  ! Check arrays (which may or may not be allocated)
1193  is_equal = is_equal .AND. &
1194  all(x%Upwelling_Overcast_Radiance .equalto. y%Upwelling_Overcast_Radiance ) .AND. &
1195  all(x%Upwelling_Radiance .equalto. y%Upwelling_Radiance ) .AND. &
1196  all(x%Layer_Optical_Depth .equalto. y%Layer_Optical_Depth )
1197  END IF
1198 
1199  END FUNCTION crtm_rtsolution_equal
1200 
1201 
1202 !--------------------------------------------------------------------------------
1203 !
1204 ! NAME:
1205 ! CRTM_RTSolution_Add
1206 !
1207 ! PURPOSE:
1208 ! Pure function to add two CRTM RTSolution objects.
1209 ! Used in OPERATOR(+) interface block.
1210 !
1211 ! CALLING SEQUENCE:
1212 ! rtssum = CRTM_RTSolution_Add( rts1, rts2 )
1213 !
1214 ! or
1215 !
1216 ! rtssum = rts1 + rts2
1217 !
1218 !
1219 ! INPUTS:
1220 ! rts1, rts2: The RTSolution objects to add.
1221 ! UNITS: N/A
1222 ! TYPE: CRTM_RTSolution_type
1223 ! DIMENSION: Scalar
1224 ! ATTRIBUTES: INTENT(IN OUT)
1225 !
1226 ! RESULT:
1227 ! rtssum: RTSolution object containing the summed components.
1228 ! UNITS: N/A
1229 ! TYPE: CRTM_RTSolution_type
1230 ! DIMENSION: Scalar
1231 !
1232 !--------------------------------------------------------------------------------
1233 
1234  ELEMENTAL FUNCTION crtm_rtsolution_add( rts1, rts2 ) RESULT( rtssum )
1235  TYPE(crtm_rtsolution_type), INTENT(IN) :: rts1, rts2
1236  TYPE(crtm_rtsolution_type) :: rtssum
1237  INTEGER :: k
1238 
1239  ! Check input
1240  ! ...If input structure association status different, do nothing
1241  IF ( crtm_rtsolution_associated(rts1) .NEQV. crtm_rtsolution_associated(rts2) ) RETURN
1242  ! ...If input structure for different sensors, do nothing
1243  IF ( (rts1%Sensor_ID /= rts2%Sensor_ID ) .AND. &
1244  (rts1%WMO_Satellite_ID /= rts2%WMO_Satellite_ID ) .AND. &
1245  (rts1%WMO_Sensor_ID /= rts2%WMO_Sensor_ID ) .AND. &
1246  (rts1%Sensor_Channel /= rts2%Sensor_Channel ) ) RETURN
1247 
1248  ! Copy the first structure
1249  rtssum = rts1
1250 
1251  ! And add the second one's components to it
1252  ! ...Handle RT_Algorithm_Name
1253  rtssum%RT_Algorithm_Name = 'Object add'
1254  ! ...The scalar values
1255  rtssum%SOD = rtssum%SOD + rts2%SOD
1256  rtssum%Surface_Emissivity = rtssum%Surface_Emissivity + rts2%Surface_Emissivity
1257  rtssum%Surface_Reflectivity = rtssum%Surface_Reflectivity + rts2%Surface_Reflectivity
1258  rtssum%Up_Radiance = rtssum%Up_Radiance + rts2%Up_Radiance
1259  rtssum%Down_Radiance = rtssum%Down_Radiance + rts2%Down_Radiance
1260  rtssum%Down_Solar_Radiance = rtssum%Down_Solar_Radiance + rts2%Down_Solar_Radiance
1261  rtssum%Surface_Planck_Radiance = rtssum%Surface_Planck_Radiance + rts2%Surface_Planck_Radiance
1262  rtssum%Radiance = rtssum%Radiance + rts2%Radiance
1263  rtssum%Brightness_Temperature = rtssum%Brightness_Temperature + rts2%Brightness_Temperature
1264  ! ...The arrays (which may or may not be allocated)
1265  IF ( crtm_rtsolution_associated(rts1) .AND. crtm_rtsolution_associated(rts2) ) THEN
1266  k = rts1%n_Layers
1267  rtssum%Upwelling_Overcast_Radiance(1:k) = rtssum%Upwelling_Overcast_Radiance(1:k) + &
1268  rts2%Upwelling_Overcast_Radiance(1:k)
1269 
1270  rtssum%Upwelling_Radiance(1:k) = rtssum%Upwelling_Radiance(1:k) + &
1271  rts2%Upwelling_Radiance(1:k)
1272 
1273  rtssum%Layer_Optical_Depth(1:k) = rtssum%Layer_Optical_Depth(1:k) + &
1274  rts2%Layer_Optical_Depth(1:k)
1275  END IF
1276 
1277  END FUNCTION crtm_rtsolution_add
1278 
1279 
1280 !--------------------------------------------------------------------------------
1281 !
1282 ! NAME:
1283 ! CRTM_RTSolution_Subtract
1284 !
1285 ! PURPOSE:
1286 ! Pure function to subtract two CRTM RTSolution objects.
1287 ! Used in OPERATOR(-) interface block.
1288 !
1289 ! CALLING SEQUENCE:
1290 ! rtsdiff = CRTM_RTSolution_Subtract( rts1, rts2 )
1291 !
1292 ! or
1293 !
1294 ! rtsdiff = rts1 - rts2
1295 !
1296 !
1297 ! INPUTS:
1298 ! rts1, rts2: The RTSolution objects to difference.
1299 ! UNITS: N/A
1300 ! TYPE: CRTM_RTSolution_type
1301 ! DIMENSION: Scalar
1302 ! ATTRIBUTES: INTENT(IN OUT)
1303 !
1304 ! RESULT:
1305 ! rtsdiff: RTSolution object containing the differenced components.
1306 ! UNITS: N/A
1307 ! TYPE: CRTM_RTSolution_type
1308 ! DIMENSION: Scalar
1309 !
1310 !--------------------------------------------------------------------------------
1311 
1312  ELEMENTAL FUNCTION crtm_rtsolution_subtract( rts1, rts2 ) RESULT( rtsdiff )
1313  TYPE(crtm_rtsolution_type), INTENT(IN) :: rts1, rts2
1314  TYPE(crtm_rtsolution_type) :: rtsdiff
1315  INTEGER :: k
1316 
1317  ! Check input
1318  ! ...If input structure association status different, do nothing
1319  IF ( crtm_rtsolution_associated(rts1) .NEQV. crtm_rtsolution_associated(rts2) ) RETURN
1320  ! ...If input structure for different sensors, do nothing
1321  IF ( (rts1%Sensor_ID /= rts2%Sensor_ID ) .AND. &
1322  (rts1%WMO_Satellite_ID /= rts2%WMO_Satellite_ID ) .AND. &
1323  (rts1%WMO_Sensor_ID /= rts2%WMO_Sensor_ID ) .AND. &
1324  (rts1%Sensor_Channel /= rts2%Sensor_Channel ) ) RETURN
1325 
1326  ! Copy the first structure
1327  rtsdiff = rts1
1328 
1329  ! And subtract the second one's components from it
1330  ! ...Handle RT_Algorithm_Name
1331  rtsdiff%RT_Algorithm_Name = 'Object subtract'
1332  ! ...The scalar values
1333  rtsdiff%SOD = rtsdiff%SOD - rts2%SOD
1334  rtsdiff%Surface_Emissivity = rtsdiff%Surface_Emissivity - rts2%Surface_Emissivity
1335  rtsdiff%Surface_Reflectivity = rtsdiff%Surface_Reflectivity - rts2%Surface_Reflectivity
1336  rtsdiff%Up_Radiance = rtsdiff%Up_Radiance - rts2%Up_Radiance
1337  rtsdiff%Down_Radiance = rtsdiff%Down_Radiance - rts2%Down_Radiance
1338  rtsdiff%Down_Solar_Radiance = rtsdiff%Down_Solar_Radiance - rts2%Down_Solar_Radiance
1339  rtsdiff%Surface_Planck_Radiance = rtsdiff%Surface_Planck_Radiance - rts2%Surface_Planck_Radiance
1340  rtsdiff%Radiance = rtsdiff%Radiance - rts2%Radiance
1341  rtsdiff%Brightness_Temperature = rtsdiff%Brightness_Temperature - rts2%Brightness_Temperature
1342  ! ...The arrays (which may or may not be allocated)
1343  IF ( crtm_rtsolution_associated(rts1) .AND. crtm_rtsolution_associated(rts2) ) THEN
1344  k = rts1%n_Layers
1345  rtsdiff%Upwelling_Overcast_Radiance(1:k) = rtsdiff%Upwelling_Overcast_Radiance(1:k) - &
1346  rts2%Upwelling_Overcast_Radiance(1:k)
1347 
1348  rtsdiff%Upwelling_Radiance(1:k) = rtsdiff%Upwelling_Radiance(1:k) - &
1349  rts2%Upwelling_Radiance(1:k)
1350 
1351  rtsdiff%Layer_Optical_Depth(1:k) = rtsdiff%Layer_Optical_Depth(1:k) - &
1352  rts2%Layer_Optical_Depth(1:k)
1353  END IF
1354 
1355  END FUNCTION crtm_rtsolution_subtract
1356 
1357 
1358 !--------------------------------------------------------------------------------
1359 !
1360 ! NAME:
1361 ! CRTM_RTSolution_Exponent
1362 !
1363 ! PURPOSE:
1364 ! Elemental utility function to raise the components of a CRTM RTSolution
1365 ! object to the supplied integer power
1366 !
1367 ! Used to compute RTSolution statistics
1368 !
1369 ! CALLING SEQUENCE:
1370 ! rts_power = CRTM_RTSolution_Exponent( rts, power )
1371 !
1372 ! OBJECTS:
1373 ! rts: RTSolution structure which is to have its members values
1374 ! raised to an integer power.
1375 ! UNITS: N/A
1376 ! TYPE: CRTM_RTSolution_type
1377 ! DIMENSION: Scalar or any rank
1378 ! ATTRIBUTES: INTENT(IN)
1379 !
1380 ! INPUTS:
1381 ! power: Exponent power to be used.
1382 ! UNITS: N/A
1383 ! TYPE: INRTGER
1384 ! DIMENSION: Same as input rts object
1385 ! ATTRIBUTES: INTENT(IN)
1386 !
1387 ! FUNCTION RESULT:
1388 ! rts_power: RTSolution structure containing the exponent result.
1389 ! UNITS: N/A
1390 ! TYPE: CRTM_RTSolution_type
1391 ! DIMENSION: Same as input rts object
1392 !
1393 !--------------------------------------------------------------------------------
1394 
1395  ELEMENTAL FUNCTION crtm_rtsolution_exponent( rts, power ) RESULT( rts_power )
1396  TYPE(crtm_rtsolution_type), INTENT(IN) :: rts
1397  INTEGER , INTENT(IN) :: power
1398  TYPE(crtm_rtsolution_type) :: rts_power
1399  INTEGER :: k
1400 
1401  ! Copy the structure
1402  rts_power = rts
1403 
1404  ! Raise the components to the supplied power
1405  ! ...Handle RT_Algorithm_Name
1406  rts_power%RT_Algorithm_Name = 'Object exponent'
1407  ! ...The scalar values
1408  rts_power%SOD = (rts_power%SOD)**power
1409  rts_power%Surface_Emissivity = (rts_power%Surface_Emissivity)**power
1410  rts_power%Surface_Reflectivity = (rts_power%Surface_Reflectivity)**power
1411  rts_power%Up_Radiance = (rts_power%Up_Radiance)**power
1412  rts_power%Down_Radiance = (rts_power%Down_Radiance)**power
1413  rts_power%Down_Solar_Radiance = (rts_power%Down_Solar_Radiance)**power
1414  rts_power%Surface_Planck_Radiance = (rts_power%Surface_Planck_Radiance)**power
1415  rts_power%Radiance = (rts_power%Radiance)**power
1416  rts_power%Brightness_Temperature = (rts_power%Brightness_Temperature)**power
1417  ! ...The arrays (which may or may not be allocated)
1418  IF ( crtm_rtsolution_associated(rts) ) THEN
1419  k = rts%n_Layers
1420  rts_power%Upwelling_Overcast_Radiance(1:k) = (rts_power%Upwelling_Overcast_Radiance(1:k))**power
1421  rts_power%Upwelling_Radiance(1:k) = (rts_power%Upwelling_Radiance(1:k))**power
1422  rts_power%Layer_Optical_Depth(1:k) = (rts_power%Layer_Optical_Depth(1:k))**power
1423  END IF
1424 
1425  END FUNCTION crtm_rtsolution_exponent
1426 
1427 
1428 !--------------------------------------------------------------------------------
1429 !
1430 ! NAME:
1431 ! CRTM_RTSolution_Normalise
1432 !
1433 ! PURPOSE:
1434 ! Elemental utility function to normalise the components of
1435 ! a CRTM RTSolution object.
1436 !
1437 ! Used to compute RTSolution statistics
1438 !
1439 ! CALLING SEQUENCE:
1440 ! rts_normal = CRTM_RTSolution_Normalise( rts, factor )
1441 !
1442 ! OBJECTS:
1443 ! rts: RTSolution structure which is to have its members values
1444 ! normalised.
1445 ! UNITS: N/A
1446 ! TYPE: CRTM_RTSolution_type
1447 ! DIMENSION: Scalar or any rank
1448 ! ATTRIBUTES: INTENT(IN)
1449 !
1450 ! INPUTS:
1451 ! factor: Normalisation factor to be used.
1452 ! UNITS: N/A
1453 ! TYPE: REAL(fp)
1454 ! DIMENSION: Same as input rts object
1455 ! ATTRIBUTES: INTENT(IN)
1456 !
1457 ! FUNCTION RESULT:
1458 ! rts_normal: RTSolution structure containing the normalised input
1459 ! object.
1460 ! UNITS: N/A
1461 ! TYPE: CRTM_RTSolution_type
1462 ! DIMENSION: Same as input rts object
1463 !
1464 !--------------------------------------------------------------------------------
1465 
1466  ELEMENTAL FUNCTION crtm_rtsolution_normalise( rts, factor ) RESULT( rts_normal )
1467  TYPE(crtm_rtsolution_type), INTENT(IN) :: rts
1468  REAL(fp) , INTENT(IN) :: factor
1469  TYPE(crtm_rtsolution_type) :: rts_normal
1470  INTEGER :: k
1471 
1472  ! Copy the structure
1473  rts_normal = rts
1474 
1475  ! Raise the components to the supplied normal
1476  ! ...Handle RT_Algorithm_Name
1477  rts_normal%RT_Algorithm_Name = 'Object normalise'
1478  ! ...The scalar values
1479  rts_normal%SOD = rts_normal%SOD/factor
1480  rts_normal%Surface_Emissivity = rts_normal%Surface_Emissivity/factor
1481  rts_normal%Surface_Reflectivity = rts_normal%Surface_Reflectivity/factor
1482  rts_normal%Up_Radiance = rts_normal%Up_Radiance/factor
1483  rts_normal%Down_Radiance = rts_normal%Down_Radiance/factor
1484  rts_normal%Down_Solar_Radiance = rts_normal%Down_Solar_Radiance/factor
1485  rts_normal%Surface_Planck_Radiance = rts_normal%Surface_Planck_Radiance/factor
1486  rts_normal%Radiance = rts_normal%Radiance/factor
1487  rts_normal%Brightness_Temperature = rts_normal%Brightness_Temperature/factor
1488  ! ...The arrays (which may or may not be allocated)
1489  IF ( crtm_rtsolution_associated(rts) ) THEN
1490  k = rts%n_Layers
1491  rts_normal%Upwelling_Overcast_Radiance(1:k) = rts_normal%Upwelling_Overcast_Radiance(1:k)/factor
1492  rts_normal%Upwelling_Radiance(1:k) = rts_normal%Upwelling_Radiance(1:k)/factor
1493  rts_normal%Layer_Optical_Depth(1:k) = rts_normal%Layer_Optical_Depth(1:k)/factor
1494  END IF
1495 
1496  END FUNCTION crtm_rtsolution_normalise
1497 
1498 
1499 !--------------------------------------------------------------------------------
1500 !
1501 ! NAME:
1502 ! CRTM_RTSolution_Sqrt
1503 !
1504 ! PURPOSE:
1505 ! Elemental utility function to compute the SQRT() of the components of
1506 ! a CRTM RTSolution object.
1507 !
1508 ! Used to compute RTSolution statistics
1509 !
1510 ! CALLING SEQUENCE:
1511 ! rts_sqrt = CRTM_RTSolution_Sqrt( rts )
1512 !
1513 ! OBJECTS:
1514 ! rts: RTSolution structure which is to have the square root
1515 ! taken of its member's vales.
1516 ! UNITS: N/A
1517 ! TYPE: CRTM_RTSolution_type
1518 ! DIMENSION: Scalar or any rank
1519 ! ATTRIBUTES: INTENT(IN)
1520 !
1521 ! FUNCTION RESULT:
1522 ! rts_sqrt: RTSolution structure containing the square root of the
1523 ! input object.
1524 ! UNITS: N/A
1525 ! TYPE: CRTM_RTSolution_type
1526 ! DIMENSION: Same as input rts object
1527 !
1528 !--------------------------------------------------------------------------------
1529 
1530  ELEMENTAL FUNCTION crtm_rtsolution_sqrt( rts ) RESULT( rts_sqrt )
1531  TYPE(crtm_rtsolution_type), INTENT(IN) :: rts
1532  TYPE(crtm_rtsolution_type) :: rts_sqrt
1533  INTEGER :: k
1534 
1535  ! Copy the structure
1536  rts_sqrt = rts
1537 
1538  ! Raise the components to the supplied normal
1539  ! ...Handle RT_Algorithm_Name
1540  rts_sqrt%RT_Algorithm_Name = 'Object SQRT()'
1541  ! ...The scalar values
1542  rts_sqrt%SOD = sqrt(rts_sqrt%SOD)
1543  rts_sqrt%Surface_Emissivity = sqrt(rts_sqrt%Surface_Emissivity)
1544  rts_sqrt%Surface_Reflectivity = sqrt(rts_sqrt%Surface_Reflectivity)
1545  rts_sqrt%Up_Radiance = sqrt(rts_sqrt%Up_Radiance)
1546  rts_sqrt%Down_Radiance = sqrt(rts_sqrt%Down_Radiance)
1547  rts_sqrt%Down_Solar_Radiance = sqrt(rts_sqrt%Down_Solar_Radiance)
1548  rts_sqrt%Surface_Planck_Radiance = sqrt(rts_sqrt%Surface_Planck_Radiance)
1549  rts_sqrt%Radiance = sqrt(rts_sqrt%Radiance)
1550  rts_sqrt%Brightness_Temperature = sqrt(rts_sqrt%Brightness_Temperature)
1551  ! ...The arrays (which may or may not be allocated)
1552  IF ( crtm_rtsolution_associated(rts) ) THEN
1553  k = rts%n_Layers
1554  rts_sqrt%Upwelling_Overcast_Radiance(1:k) = sqrt(rts_sqrt%Upwelling_Overcast_Radiance(1:k))
1555  rts_sqrt%Upwelling_Radiance(1:k) = sqrt(rts_sqrt%Upwelling_Radiance(1:k))
1556  rts_sqrt%Layer_Optical_Depth(1:k) = sqrt(rts_sqrt%Layer_Optical_Depth(1:k))
1557  END IF
1558 
1559  END FUNCTION crtm_rtsolution_sqrt
1560 
1561 
1562 !
1563 ! NAME:
1564 ! Read_Record
1565 !
1566 ! PURPOSE:
1567 ! Utility function to read a single RTSolution data record
1568 !
1569 
1570  FUNCTION read_record( &
1571  fid, & ! Input
1572  rts, & ! Output
1573  old_version) & ! Optional input
1574  result( err_stat )
1575  ! Arguments
1576  INTEGER, INTENT(IN) :: fid
1577  TYPE(crtm_rtsolution_type), INTENT(OUT) :: rts
1578  LOGICAL, OPTIONAL, INTENT(IN) :: old_version
1579  ! Function result
1580  INTEGER :: err_stat
1581  ! Function parameters
1582  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_RTSolution_ReadFile(Record)'
1583  ! Function variables
1584  CHARACTER(ML) :: msg
1585  CHARACTER(ML) :: io_msg
1586  INTEGER :: io_stat
1587  INTEGER :: n_layers
1588  LOGICAL :: current_version
1589 
1590  ! Set up
1591  err_stat = success
1592  ! ...PRocess optional arguments
1593  current_version = .true.
1594  IF ( PRESENT(old_version) ) current_version = .NOT. old_version
1595 
1596  ! Read the dimensions
1597  READ( fid,iostat=io_stat,iomsg=io_msg ) n_layers
1598  IF ( io_stat /= 0 ) THEN
1599  msg = 'Error reading dimensions - '//trim(io_msg)
1600  CALL read_record_cleanup(); RETURN
1601  END IF
1602 
1603 
1604  ! Allocate the RTSolution structure if necessary
1605  IF ( n_layers > 0 ) THEN
1606  CALL crtm_rtsolution_create( rts, n_layers )
1607  IF ( .NOT. crtm_rtsolution_associated( rts ) ) THEN
1608  msg = 'Error creating output object.'
1609  CALL read_record_cleanup(); RETURN
1610  END IF
1611  END IF
1612 
1613 
1614  ! Read the sensor info
1615  READ( fid,iostat=io_stat,iomsg=io_msg ) &
1616  rts%Sensor_Id , &
1617  rts%WMO_Satellite_Id, &
1618  rts%WMO_Sensor_Id , &
1619  rts%Sensor_Channel
1620  IF ( io_stat /= 0 ) THEN
1621  msg = 'Error reading sensor information - '//trim(io_msg)
1622  CALL read_record_cleanup(); RETURN
1623  END IF
1624 
1625 
1626  ! Read the RT algorithm name
1627  READ( fid,iostat=io_stat,iomsg=io_msg ) &
1628  rts%RT_Algorithm_Name
1629  IF ( io_stat /= 0 ) THEN
1630  msg = 'Error reading RT Algorithm Name'//trim(io_msg)
1631  CALL read_record_cleanup(); RETURN
1632  END IF
1633 
1634 
1635  ! Read the forward radiative transfer intermediate results
1636  READ( fid,iostat=io_stat,iomsg=io_msg ) &
1637  rts%SOD , &
1638  rts%Surface_Emissivity , &
1639  rts%Surface_Reflectivity , &
1640  rts%Up_Radiance , &
1641  rts%Down_Radiance , &
1642  rts%Down_Solar_Radiance , &
1643  rts%Surface_Planck_Radiance
1644  IF ( io_stat /= 0 ) THEN
1645  msg = 'Error reading scalar intermediate results - '//trim(io_msg)
1646  CALL read_record_cleanup(); RETURN
1647  END IF
1648  IF ( n_layers > 0 ) THEN
1649  IF ( current_version ) THEN
1650  READ( fid,iostat=io_stat,iomsg=io_msg ) &
1651  rts%Upwelling_Overcast_Radiance , &
1652  rts%Upwelling_Radiance, &
1653  rts%Layer_Optical_Depth
1654  ELSE
1655  READ( fid,iostat=io_stat,iomsg=io_msg ) &
1656  rts%Upwelling_Radiance , &
1657  rts%Layer_Optical_Depth
1658  END IF
1659  IF ( io_stat /= 0 ) THEN
1660  msg = 'Error reading array intermediate results - '//trim(io_msg)
1661  CALL read_record_cleanup(); RETURN
1662  END IF
1663  END IF
1664 
1665 
1666  ! Read the radiative transfer results
1667  READ( fid,iostat=io_stat,iomsg=io_msg ) &
1668  rts%Radiance , &
1669  rts%Brightness_Temperature
1670  IF ( io_stat /= 0 ) THEN
1671  msg = 'Error reading result data - '//trim(io_msg)
1672  CALL read_record_cleanup(); RETURN
1673  END IF
1674 
1675  CONTAINS
1676 
1677  SUBROUTINE read_record_cleanup()
1679  CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1680  IF ( io_stat /= success ) &
1681  msg = trim(msg)//'; Error closing file during error cleanup - '//trim(io_msg)
1682  err_stat = failure
1683  CALL display_message( routine_name, msg, err_stat )
1684  END SUBROUTINE read_record_cleanup
1685 
1686  END FUNCTION read_record
1687 
1688 
1689 !
1690 ! NAME:
1691 ! Write_Record
1692 !
1693 ! PURPOSE:
1694 ! Function to write a single RTSolution data record
1695 !
1696 
1697  FUNCTION write_record( &
1698  fid, & ! Input
1699  rts) & ! Input
1700  result( err_stat )
1701  ! Arguments
1702  INTEGER, INTENT(IN) :: fid
1703  TYPE(crtm_rtsolution_type), INTENT(IN) :: rts
1704  ! Function result
1705  INTEGER :: err_stat
1706  ! Function parameters
1707  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_RTSolution_WriteFile(Record)'
1708  ! Function variables
1709  CHARACTER(ML) :: msg
1710  CHARACTER(ML) :: io_msg
1711  INTEGER :: io_stat
1712 
1713  ! Set up
1714  err_stat = success
1715 
1716 
1717  ! Write the data dimensions
1718  WRITE( fid,iostat=io_stat,iomsg=io_msg ) rts%n_Layers
1719  IF ( io_stat /= 0 ) THEN
1720  msg = 'Error writing dimensions - '//trim(io_msg)
1721  CALL write_record_cleanup(); RETURN
1722  END IF
1723 
1724 
1725  ! Write the sensor info
1726  WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
1727  rts%Sensor_Id , &
1728  rts%WMO_Satellite_Id, &
1729  rts%WMO_Sensor_Id , &
1730  rts%Sensor_Channel
1731  IF ( io_stat /= 0 ) THEN
1732  msg = 'Error writing sensor information - '//trim(io_msg)
1733  CALL write_record_cleanup(); RETURN
1734  END IF
1735 
1736 
1737  ! Write the sensor info
1738  WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
1739  rts%RT_Algorithm_Name
1740  IF ( io_stat /= 0 ) THEN
1741  msg = 'Error writing RT Algorithm Name'//trim(io_msg)
1742  CALL write_record_cleanup(); RETURN
1743  END IF
1744 
1745 
1746  ! Write the forward radiative transfer intermediate results
1747  WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
1748  rts%SOD , &
1749  rts%Surface_Emissivity , &
1750  rts%Surface_Reflectivity , &
1751  rts%Up_Radiance , &
1752  rts%Down_Radiance , &
1753  rts%Down_Solar_Radiance , &
1754  rts%Surface_Planck_Radiance
1755  IF ( io_stat /= 0 ) THEN
1756  msg = 'Error writing scalar intermediate results - '//trim(io_msg)
1757  CALL write_record_cleanup(); RETURN
1758  END IF
1759  IF ( rts%n_Layers > 0 ) THEN
1760  WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
1761  rts%Upwelling_Overcast_Radiance , &
1762  rts%Upwelling_Radiance, &
1763  rts%Layer_Optical_Depth
1764  IF ( io_stat /= 0 ) THEN
1765  msg = 'Error writing array intermediate results - '//trim(io_msg)
1766  CALL write_record_cleanup(); RETURN
1767  END IF
1768  END IF
1769 
1770 
1771  ! Write the radiative transfer results
1772  WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
1773  rts%Radiance , &
1774  rts%Brightness_Temperature
1775  IF ( io_stat /= 0 ) THEN
1776  msg = 'Error writing result data - '//trim(io_msg)
1777  CALL write_record_cleanup(); RETURN
1778  END IF
1779 
1780  CONTAINS
1781 
1782  SUBROUTINE write_record_cleanup()
1783  CLOSE( fid,status=write_error_status,iostat=io_stat,iomsg=io_msg )
1784  IF ( io_stat /= 0 ) &
1785  msg = trim(msg)//'; Error closing file during error cleanup - '//trim(io_msg)
1786  err_stat = failure
1787  CALL display_message( routine_name, msg, err_stat )
1788  END SUBROUTINE write_record_cleanup
1789 
1790  END FUNCTION write_record
1791 
1792 END MODULE crtm_rtsolution_define
elemental type(crtm_rtsolution_type) function crtm_rtsolution_subtract(rts1, rts2)
elemental type(crtm_rtsolution_type) function crtm_rtsolution_normalise(rts, factor)
elemental type(crtm_rtsolution_type) function crtm_rtsolution_exponent(rts, power)
subroutine scalar_inspect(RTSolution, Unit)
integer, parameter, public failure
integer, parameter, public strlen
integer, parameter, public warning
elemental logical function, public crtm_rtsolution_compare(x, y, n_SigFig)
elemental subroutine, public crtm_rtsolution_zero(RTSolution)
integer function, public crtm_rtsolution_statistics(rts, rts_stats)
integer, parameter, public fp
Definition: Type_Kinds.f90:124
integer function, public readgatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
character(*), parameter write_error_status
elemental type(crtm_rtsolution_type) function crtm_rtsolution_sqrt(rts)
subroutine rank2_inspect(RTSolution, Unit)
subroutine inquire_cleanup()
integer function, public crtm_rtsolution_inquirefile(Filename, n_Channels, n_Profiles)
subroutine read_cleanup()
integer function, public crtm_rtsolution_readfile(Filename, RTSolution, Quiet, n_Channels, n_Profiles, Old_Version, Debug)
subroutine write_cleanup()
subroutine read_record_cleanup()
elemental logical function, public crtm_rtsolution_associated(RTSolution)
integer function, public open_binary_file(Filename, FileID, For_Output, No_Check)
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
integer, parameter, public invalid_wmo_satellite_id
integer function read_record(fid, rts, old_version)
elemental subroutine, public crtm_rtsolution_destroy(RTSolution)
integer, parameter, public default_n_sigfig
integer, parameter, public invalid_sensor
integer, parameter, public invalid_wmo_sensor_id
integer function, public writegatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
subroutine write_record_cleanup()
character(*), parameter module_version_id
elemental type(crtm_rtsolution_type) function crtm_rtsolution_add(rts1, rts2)
elemental subroutine, public crtm_rtsolution_create(RTSolution, n_Layers)
subroutine, public crtm_rtsolution_defineversion(Id)
#define min(a, b)
Definition: mosaic_util.h:32
elemental logical function crtm_rtsolution_equal(x, y)
integer, parameter, public success
integer, parameter, public information
integer function, public crtm_rtsolution_writefile(Filename, RTSolution, Quiet, Debug)