FV3 Bundle
CRTM_Geometry_Define.f90
Go to the documentation of this file.
1 !
2 ! CRTM_Geometry_Define
3 !
4 ! Module defining the CRTM Geometry data structure.
5 !
6 !
7 ! CREATION HISTORY:
8 ! Written by: Paul van Delst, 18-Nov-2009
9 ! paul.vandelst@noaa.gov
10 !
11 
13 
14  ! ------------------
15  ! Environment set up
16  ! ------------------
17  ! Intrinsic modules
18  USE iso_fortran_env , ONLY: output_unit
19  ! Module use
20  USE type_kinds , ONLY: fp
23  OPERATOR(.equalto.), &
29  USE date_utility , ONLY: daysinmonth
39  ! Disable implicit typing
40  IMPLICIT NONE
41 
42 
43  ! ------------
44  ! Visibilities
45  ! ------------
46  ! Everything private by default
47  PRIVATE
48  ! Operators
49  PUBLIC :: OPERATOR(==)
50  PUBLIC :: OPERATOR(-)
51  ! Geometry enitities
52  ! ...Structures
53  PUBLIC :: crtm_geometry_type
54  ! ...Procedures
55  PUBLIC :: crtm_geometry_associated
56  PUBLIC :: crtm_geometry_destroy
57  PUBLIC :: crtm_geometry_create
58  PUBLIC :: crtm_geometry_setvalue
59  PUBLIC :: crtm_geometry_getvalue
60  PUBLIC :: crtm_geometry_isvalid
61  PUBLIC :: crtm_geometry_inspect
63  PUBLIC :: crtm_geometry_compare
65  PUBLIC :: crtm_geometry_readfile
66  PUBLIC :: crtm_geometry_writefile
67  PUBLIC :: crtm_geometry_readrecord
69 
70 
71  ! ---------------------
72  ! Procedure overloading
73  ! ---------------------
74  INTERFACE OPERATOR(==)
75  MODULE PROCEDURE crtm_geometry_equal
76  END INTERFACE OPERATOR(==)
77 
78  INTERFACE OPERATOR(-)
79  MODULE PROCEDURE crtm_geometry_subtract
80  END INTERFACE OPERATOR(-)
81 
82 
83  ! -----------------
84  ! Module parameters
85  ! -----------------
86  CHARACTER(*), PARAMETER :: module_version_id = &
87  '$Id: CRTM_Geometry_Define.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
88  ! Literal constants
89  REAL(fp), PARAMETER :: zero = 0.0_fp
90  ! Message string length
91  INTEGER, PARAMETER :: ml = 256
92  ! File status on close after write error
93  CHARACTER(*), PARAMETER :: write_error_status = 'DELETE'
94  ! Invalid date values
95  INTEGER, PARAMETER :: min_year = 1960 ! Vanguard 2, was launched on February 17, 1959
96 
97 
98  ! ---------------------------------
99  ! Geometry data type definition
100  ! ---------------------------------
101  !:tdoc+:
103  ! Allocation indicator
104  LOGICAL :: is_allocated = .false.
105  ! Field of view index (1-nFOV)
106  INTEGER :: ifov = 0
107  ! Earth location
108  REAL(fp) :: longitude = zero
109  REAL(fp) :: latitude = zero
110  REAL(fp) :: surface_altitude = zero
111  ! Sensor angle information
112  REAL(fp) :: sensor_scan_angle = zero
113  REAL(fp) :: sensor_zenith_angle = zero
114  REAL(fp) :: sensor_azimuth_angle = 999.9_fp ! Invalid marker
115  ! Source angle information
116  REAL(fp) :: source_zenith_angle = 100.0_fp ! Below horizon
117  REAL(fp) :: source_azimuth_angle = zero
118  ! Flux angle information
119  REAL(fp) :: flux_zenith_angle = diffusivity_angle
120  ! Date for geometry calculations
121  INTEGER :: year = 2001
122  INTEGER :: month = 1
123  INTEGER :: day = 1
124  END TYPE crtm_geometry_type
125  !:tdoc-:
126 
127 
128 CONTAINS
129 
130 
131 !##################################################################################
132 !##################################################################################
133 !## ##
134 !## ## PUBLIC MODULE ROUTINES ## ##
135 !## ##
136 !##################################################################################
137 !##################################################################################
138 
139 
140 !--------------------------------------------------------------------------------
141 !:sdoc+:
142 !
143 ! NAME:
144 ! CRTM_Geometry_Associated
145 !
146 ! PURPOSE:
147 ! Elemental function to test the status of the allocatable components
148 ! of a CRTM Geometry object.
149 !
150 ! CALLING SEQUENCE:
151 ! Status = CRTM_Geometry_Associated( geo )
152 !
153 ! OBJECTS:
154 ! geo: Geometry structure which is to have its member's
155 ! status tested.
156 ! UNITS: N/A
157 ! TYPE: CRTM_Geometry_type
158 ! DIMENSION: Scalar or any rank
159 ! ATTRIBUTES: INTENT(IN)
160 !
161 ! FUNCTION RESULT:
162 ! Status: The return value is a logical value indicating the
163 ! status of the Geometry members.
164 ! .TRUE. - if the array components are allocated.
165 ! .FALSE. - if the array components are not allocated.
166 ! UNITS: N/A
167 ! TYPE: LOGICAL
168 ! DIMENSION: Same as input Geometry argument
169 !
170 !:sdoc-:
171 !--------------------------------------------------------------------------------
172 
173  ELEMENTAL FUNCTION crtm_geometry_associated( Geometry ) RESULT( Status )
174  TYPE(crtm_geometry_type), INTENT(IN) :: geometry
175  LOGICAL :: status
176  status = geometry%Is_Allocated
177  END FUNCTION crtm_geometry_associated
178 
179 
180 !--------------------------------------------------------------------------------
181 !:sdoc+:
182 !
183 ! NAME:
184 ! CRTM_Geometry_Destroy
185 !
186 ! PURPOSE:
187 ! Elemental subroutine to re-initialize CRTM Geometry objects.
188 !
189 ! CALLING SEQUENCE:
190 ! CALL CRTM_Geometry_Destroy( geo )
191 !
192 ! OBJECTS:
193 ! geo: Re-initialized Geometry structure.
194 ! UNITS: N/A
195 ! TYPE: CRTM_Geometry_type
196 ! DIMENSION: Scalar or any rank
197 ! ATTRIBUTES: INTENT(OUT)
198 !
199 !:sdoc-:
200 !--------------------------------------------------------------------------------
201 
202  ELEMENTAL SUBROUTINE crtm_geometry_destroy( geo )
203  TYPE(crtm_geometry_type), INTENT(OUT) :: geo
204  geo%Is_Allocated = .false. ! Placeholder for future expansion
205  END SUBROUTINE crtm_geometry_destroy
206 
207 
208 !--------------------------------------------------------------------------------
209 !:sdoc+:
210 !
211 ! NAME:
212 ! CRTM_Geometry_Create
213 !
214 ! PURPOSE:
215 ! Elemental subroutine to create an instance of the CRTM Geometry object.
216 !
217 ! CALLING SEQUENCE:
218 ! CALL CRTM_Geometry_Create( geo )
219 !
220 ! OBJECTS:
221 ! geo: Geometry structure.
222 ! UNITS: N/A
223 ! TYPE: CRTM_Geometry_type
224 ! DIMENSION: Scalar or any rank
225 ! ATTRIBUTES: INTENT(OUT)
226 !
227 !:sdoc-:
228 !--------------------------------------------------------------------------------
229 
230  ELEMENTAL SUBROUTINE crtm_geometry_create( geo )
231  ! Arguments
232  TYPE(crtm_geometry_type), INTENT(OUT) :: geo
233 
234  ! NOTE: This is a stub routine for future expansion
235 
236  ! Set allocation indicator
237  geo%Is_Allocated = .true.
238 
239  END SUBROUTINE crtm_geometry_create
240 
241 
242 !--------------------------------------------------------------------------------
243 !:sdoc+:
244 !
245 ! NAME:
246 ! CRTM_Geometry_SetValue
247 !
248 ! PURPOSE:
249 ! Elemental subroutine to set the values of CRTM Geometry
250 ! object components.
251 !
252 ! CALLING SEQUENCE:
253 ! CALL CRTM_Geometry_SetValue( geo, &
254 ! iFOV = iFOV , &
255 ! Longitude = Longitude , &
256 ! Latitude = Latitude , &
257 ! Surface_Altitude = Surface_Altitude , &
258 ! Sensor_Scan_Angle = Sensor_Scan_Angle , &
259 ! Sensor_Zenith_Angle = Sensor_Zenith_Angle , &
260 ! Sensor_Azimuth_Angle = Sensor_Azimuth_Angle, &
261 ! Source_Zenith_Angle = Source_Zenith_Angle , &
262 ! Source_Azimuth_Angle = Source_Azimuth_Angle, &
263 ! Flux_Zenith_Angle = Flux_Zenith_Angle , &
264 ! Year = Year , &
265 ! Month = Month , &
266 ! Day = Day )
267 !
268 ! OBJECTS:
269 ! geo: Geometry object for which component values
270 ! are to be set.
271 ! UNITS: N/A
272 ! TYPE: CRTM_Geometry_type
273 ! DIMENSION: Scalar or any rank
274 ! ATTRIBUTES: INTENT(IN OUT)
275 !
276 ! OPTIONAL INPUTS:
277 ! iFOV: Sensor field-of-view index.
278 ! UNITS: N/A
279 ! TYPE: INTEGER
280 ! DIMENSION: Scalar or same as geo input
281 ! ATTRIBUTES: INTENT(IN), OPTIONAL
282 !
283 ! Longitude: Earth longitude
284 ! UNITS: degrees East (0->360)
285 ! TYPE: REAL(fp)
286 ! DIMENSION: Scalar or same as geo input
287 ! ATTRIBUTES: INTENT(IN), OPTIONAL
288 !
289 ! Latitude: Earth latitude.
290 ! UNITS: degrees North (-90->+90)
291 ! TYPE: REAL(fp)
292 ! DIMENSION: Scalar or same as geo input
293 ! ATTRIBUTES: INTENT(IN), OPTIONAL
294 !
295 ! Surface_Altitude: Altitude of the Earth's surface at the specifed
296 ! lon/lat location.
297 ! UNITS: metres (m)
298 ! TYPE: REAL(fp)
299 ! DIMENSION: Scalar or same as geo input
300 ! ATTRIBUTES: INTENT(IN), OPTIONAL
301 !
302 ! Sensor_Scan_Angle: The sensor scan angle from nadir.
303 ! UNITS: degrees
304 ! TYPE: REAL(fp)
305 ! DIMENSION: Scalar or same as geo input
306 ! ATTRIBUTES: INTENT(IN), OPTIONAL
307 !
308 ! Sensor_Zenith_Angle: The zenith angle from the field-of-view
309 ! to the sensor.
310 ! UNITS: degrees
311 ! TYPE: REAL(fp)
312 ! DIMENSION: Scalar or same as geo input
313 ! ATTRIBUTES: INTENT(IN), OPTIONAL
314 !
315 ! Sensor_Azimuth_Angle: The azimuth angle subtended by the horizontal
316 ! projection of a direct line from the satellite
317 ! to the FOV and the North-South axis measured
318 ! clockwise from North.
319 ! UNITS: degrees from North (0->360)
320 ! TYPE: REAL(fp)
321 ! DIMENSION: Scalar or same as geo input
322 ! ATTRIBUTES: INTENT(IN), OPTIONAL
323 !
324 ! Source_Zenith_Angle: The zenith angle from the field-of-view
325 ! to a source (sun or moon).
326 ! UNITS: degrees
327 ! TYPE: REAL(fp)
328 ! DIMENSION: Scalar or same as geo input
329 ! ATTRIBUTES: INTENT(IN), OPTIONAL
330 !
331 ! Source_Azimuth_Angle: The azimuth angle subtended by the horizontal
332 ! projection of a direct line from the source
333 ! to the FOV and the North-South axis measured
334 ! clockwise from North.
335 ! UNITS: degrees from North (0->360)
336 ! TYPE: REAL(fp)
337 ! DIMENSION: Scalar or same as geo input
338 ! ATTRIBUTES: INTENT(IN), OPTIONAL
339 !
340 ! Flux_Zenith_Angle: The zenith angle used to approximate downwelling
341 ! flux transmissivity
342 ! UNITS: degrees
343 ! TYPE: REAL(fp)
344 ! DIMENSION: Scalar or same as geo input
345 ! ATTRIBUTES: INTENT(IN), OPTIONAL
346 !
347 ! Year: The year in 4-digit format, e.g. 1997.
348 ! UNITS: N/A
349 ! TYPE: INTEGER
350 ! DIMENSION: Scalar or same as geo input
351 ! ATTRIBUTES: INTENT(IN), OPTIONAL
352 !
353 ! Month: The month of the year (1-12).
354 ! UNITS: N/A
355 ! TYPE: INTEGER
356 ! DIMENSION: Scalar or same as geo input
357 ! ATTRIBUTES: INTENT(IN), OPTIONAL
358 !
359 ! Day: The day of the month (1-28/29/30/31).
360 ! UNITS: N/A
361 ! TYPE: INTEGER
362 ! DIMENSION: Scalar or same as geo input
363 ! ATTRIBUTES: INTENT(IN), OPTIONAL
364 !
365 !:sdoc-:
366 !--------------------------------------------------------------------------------
367 
368  ELEMENTAL SUBROUTINE crtm_geometry_setvalue( &
369  geo , & ! In/Output
370  iFOV , & ! Optional input
371  Longitude , & ! Optional input
372  Latitude , & ! Optional input
373  Surface_Altitude , & ! Optional input
374  Sensor_Scan_Angle , & ! Optional input
375  Sensor_Zenith_Angle , & ! Optional input
376  Sensor_Azimuth_Angle, & ! Optional input
377  Source_Zenith_Angle , & ! Optional input
378  Source_Azimuth_Angle, & ! Optional input
379  Flux_Zenith_Angle , & ! Optional input
380  Year , & ! Optional input
381  Month , & ! Optional input
382  Day ) ! Optional input
383  ! Arguments
384  TYPE(crtm_geometry_type), INTENT(IN OUT) :: geo
385  INTEGER , OPTIONAL, INTENT(IN) :: ifov
386  REAL(fp), OPTIONAL, INTENT(IN) :: longitude
387  REAL(fp), OPTIONAL, INTENT(IN) :: latitude
388  REAL(fp), OPTIONAL, INTENT(IN) :: surface_altitude
389  REAL(fp), OPTIONAL, INTENT(IN) :: sensor_scan_angle
390  REAL(fp), OPTIONAL, INTENT(IN) :: sensor_zenith_angle
391  REAL(fp), OPTIONAL, INTENT(IN) :: sensor_azimuth_angle
392  REAL(fp), OPTIONAL, INTENT(IN) :: source_zenith_angle
393  REAL(fp), OPTIONAL, INTENT(IN) :: source_azimuth_angle
394  REAL(fp), OPTIONAL, INTENT(IN) :: flux_zenith_angle
395  INTEGER, OPTIONAL, INTENT(IN) :: year
396  INTEGER, OPTIONAL, INTENT(IN) :: month
397  INTEGER, OPTIONAL, INTENT(IN) :: day
398 
399  ! Set values
400  IF ( PRESENT(ifov ) ) geo%iFOV = ifov
401  IF ( PRESENT(longitude ) ) geo%Longitude = longitude
402  IF ( PRESENT(latitude ) ) geo%Latitude = latitude
403  IF ( PRESENT(surface_altitude ) ) geo%Surface_Altitude = surface_altitude
404  IF ( PRESENT(sensor_scan_angle ) ) geo%Sensor_Scan_Angle = sensor_scan_angle
405  IF ( PRESENT(sensor_zenith_angle ) ) geo%Sensor_Zenith_Angle = sensor_zenith_angle
406  IF ( PRESENT(sensor_azimuth_angle) ) geo%Sensor_Azimuth_Angle = sensor_azimuth_angle
407  IF ( PRESENT(source_zenith_angle ) ) geo%Source_Zenith_Angle = source_zenith_angle
408  IF ( PRESENT(source_azimuth_angle) ) geo%Source_Azimuth_Angle = source_azimuth_angle
409  IF ( PRESENT(flux_zenith_angle ) ) geo%Flux_Zenith_Angle = flux_zenith_angle
410  IF ( PRESENT(year ) ) geo%Year = year
411  IF ( PRESENT(month ) ) geo%Month = month
412  IF ( PRESENT(day ) ) geo%Day = day
413 
414  END SUBROUTINE crtm_geometry_setvalue
415 
416 
417 !--------------------------------------------------------------------------------
418 !:sdoc+:
419 !
420 ! NAME:
421 ! CRTM_Geometry_GetValue
422 !
423 ! PURPOSE:
424 ! Elemental subroutine to get the values of CRTM Geometry
425 ! object components.
426 !
427 ! CALLING SEQUENCE:
428 ! CALL CRTM_Geometry_GetValue( geo, &
429 ! iFOV = iFOV , &
430 ! Longitude = Longitude , &
431 ! Latitude = Latitude , &
432 ! Surface_Altitude = Surface_Altitude , &
433 ! Sensor_Scan_Angle = Sensor_Scan_Angle , &
434 ! Sensor_Zenith_Angle = Sensor_Zenith_Angle , &
435 ! Sensor_Azimuth_Angle = Sensor_Azimuth_Angle, &
436 ! Source_Zenith_Angle = Source_Zenith_Angle , &
437 ! Source_Azimuth_Angle = Source_Azimuth_Angle, &
438 ! Flux_Zenith_Angle = Flux_Zenith_Angle , &
439 ! Year = Year , &
440 ! Month = Month , &
441 ! Day = Day )
442 !
443 ! OBJECTS:
444 ! geo: Geometry object from which component values
445 ! are to be retrieved.
446 ! UNITS: N/A
447 ! TYPE: CRTM_Geometry_type
448 ! DIMENSION: Scalar or any rank
449 ! ATTRIBUTES: INTENT(IN OUT)
450 !
451 ! OPTIONAL OUTPUTS:
452 ! iFOV: Sensor field-of-view index.
453 ! UNITS: N/A
454 ! TYPE: INTEGER
455 ! DIMENSION: Scalar or same as geo input
456 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
457 !
458 ! Longitude: Earth longitude
459 ! UNITS: degrees East (0->360)
460 ! TYPE: REAL(fp)
461 ! DIMENSION: Scalar or same as geo input
462 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
463 !
464 ! Latitude: Earth latitude.
465 ! UNITS: degrees North (-90->+90)
466 ! TYPE: REAL(fp)
467 ! DIMENSION: Scalar or same as geo input
468 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
469 !
470 ! Surface_Altitude: Altitude of the Earth's surface at the specifed
471 ! lon/lat location.
472 ! UNITS: metres (m)
473 ! TYPE: REAL(fp)
474 ! DIMENSION: Scalar or same as geo input
475 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
476 !
477 ! Sensor_Scan_Angle: The sensor scan angle from nadir.
478 ! UNITS: degrees
479 ! TYPE: REAL(fp)
480 ! DIMENSION: Scalar or same as geo input
481 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
482 !
483 ! Sensor_Zenith_Angle: The zenith angle from the field-of-view
484 ! to the sensor.
485 ! UNITS: degrees
486 ! TYPE: REAL(fp)
487 ! DIMENSION: Scalar or same as geo input
488 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
489 !
490 ! Sensor_Azimuth_Angle: The azimuth angle subtended by the horizontal
491 ! projection of a direct line from the satellite
492 ! to the FOV and the North-South axis measured
493 ! clockwise from North.
494 ! UNITS: degrees from North (0->360)
495 ! TYPE: REAL(fp)
496 ! DIMENSION: Scalar or same as geo input
497 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
498 !
499 ! Source_Zenith_Angle: The zenith angle from the field-of-view
500 ! to a source (sun or moon).
501 ! UNITS: degrees
502 ! TYPE: REAL(fp)
503 ! DIMENSION: Scalar or same as geo input
504 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
505 !
506 ! Source_Azimuth_Angle: The azimuth angle subtended by the horizontal
507 ! projection of a direct line from the source
508 ! to the FOV and the North-South axis measured
509 ! clockwise from North.
510 ! UNITS: degrees from North (0->360)
511 ! TYPE: REAL(fp)
512 ! DIMENSION: Scalar or same as geo input
513 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
514 !
515 ! Flux_Zenith_Angle: The zenith angle used to approximate downwelling
516 ! flux transmissivity
517 ! UNITS: degrees
518 ! TYPE: REAL(fp)
519 ! DIMENSION: Scalar or same as geo input
520 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
521 !
522 ! Year: The year in 4-digit format, e.g. 1997.
523 ! UNITS: N/A
524 ! TYPE: INTEGER
525 ! DIMENSION: Scalar or same as geo input
526 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
527 !
528 ! Month: The month of the year (1-12).
529 ! UNITS: N/A
530 ! TYPE: INTEGER
531 ! DIMENSION: Scalar or same as geo input
532 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
533 !
534 ! Day: The day of the month (1-28/29/30/31).
535 ! UNITS: N/A
536 ! TYPE: INTEGER
537 ! DIMENSION: Scalar or same as geo input
538 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
539 !
540 !:sdoc-:
541 !--------------------------------------------------------------------------------
542 
543  ELEMENTAL SUBROUTINE crtm_geometry_getvalue( &
544  geo , & ! Input
545  iFOV , & ! Optional output
546  Longitude , & ! Optional output
547  Latitude , & ! Optional output
548  Surface_Altitude , & ! Optional output
549  Sensor_Scan_Angle , & ! Optional output
550  Sensor_Zenith_Angle , & ! Optional output
551  Sensor_Azimuth_Angle, & ! Optional output
552  Source_Zenith_Angle , & ! Optional output
553  Source_Azimuth_Angle, & ! Optional output
554  Flux_Zenith_Angle , & ! Optional output
555  Year , & ! Optional output
556  Month , & ! Optional output
557  Day ) ! Optional output
558  ! Arguments
559  TYPE(crtm_geometry_type), INTENT(IN) :: geo
560  INTEGER , OPTIONAL, INTENT(OUT) :: ifov
561  REAL(fp), OPTIONAL, INTENT(OUT) :: longitude
562  REAL(fp), OPTIONAL, INTENT(OUT) :: latitude
563  REAL(fp), OPTIONAL, INTENT(OUT) :: surface_altitude
564  REAL(fp), OPTIONAL, INTENT(OUT) :: sensor_scan_angle
565  REAL(fp), OPTIONAL, INTENT(OUT) :: sensor_zenith_angle
566  REAL(fp), OPTIONAL, INTENT(OUT) :: sensor_azimuth_angle
567  REAL(fp), OPTIONAL, INTENT(OUT) :: source_zenith_angle
568  REAL(fp), OPTIONAL, INTENT(OUT) :: source_azimuth_angle
569  REAL(fp), OPTIONAL, INTENT(OUT) :: flux_zenith_angle
570  INTEGER, OPTIONAL, INTENT(OUT) :: year
571  INTEGER, OPTIONAL, INTENT(OUT) :: month
572  INTEGER, OPTIONAL, INTENT(OUT) :: day
573 
574  ! Get values
575  IF ( PRESENT(ifov ) ) ifov = geo%iFOV
576  IF ( PRESENT(longitude ) ) longitude = geo%Longitude
577  IF ( PRESENT(latitude ) ) latitude = geo%Latitude
578  IF ( PRESENT(surface_altitude ) ) surface_altitude = geo%Surface_Altitude
579  IF ( PRESENT(sensor_scan_angle ) ) sensor_scan_angle = geo%Sensor_Scan_Angle
580  IF ( PRESENT(sensor_zenith_angle ) ) sensor_zenith_angle = geo%Sensor_Zenith_Angle
581  IF ( PRESENT(sensor_azimuth_angle) ) sensor_azimuth_angle = geo%Sensor_Azimuth_Angle
582  IF ( PRESENT(source_zenith_angle ) ) source_zenith_angle = geo%Source_Zenith_Angle
583  IF ( PRESENT(source_azimuth_angle) ) source_azimuth_angle = geo%Source_Azimuth_Angle
584  IF ( PRESENT(flux_zenith_angle ) ) flux_zenith_angle = geo%Flux_Zenith_Angle
585  IF ( PRESENT(year ) ) year = geo%Year
586  IF ( PRESENT(month ) ) month = geo%Month
587  IF ( PRESENT(day ) ) day = geo%Day
588 
589  END SUBROUTINE crtm_geometry_getvalue
590 
591 
592 !--------------------------------------------------------------------------------
593 !:sdoc+:
594 !
595 ! NAME:
596 ! CRTM_Geometry_IsValid
597 !
598 ! PURPOSE:
599 ! Non-pure function to perform some simple validity checks on a
600 ! CRTM Geometry object.
601 !
602 ! If invalid data is found, a message is printed to stdout.
603 !
604 ! CALLING SEQUENCE:
605 ! result = CRTM_Geometry_IsValid( geo )
606 !
607 ! or
608 !
609 ! IF ( CRTM_Geometry_IsValid( geo ) ) THEN....
610 !
611 ! OBJECTS:
612 ! geo: CRTM Geometry object which is to have its
613 ! contents checked.
614 ! UNITS: N/A
615 ! TYPE: CRTM_Geometry_type
616 ! DIMENSION: Scalar
617 ! ATTRIBUTES: INTENT(IN)
618 !
619 ! FUNCTION RESULT:
620 ! result: Logical variable indicating whether or not the input
621 ! passed the check.
622 ! If == .FALSE., Geometry object is unused or contains
623 ! invalid data.
624 ! == .TRUE., Geometry object can be used in CRTM.
625 ! UNITS: N/A
626 ! TYPE: LOGICAL
627 ! DIMENSION: Scalar
628 !
629 !:sdoc-:
630 !--------------------------------------------------------------------------------
631 
632  FUNCTION crtm_geometry_isvalid( geo ) RESULT( IsValid )
633  TYPE(crtm_geometry_type), INTENT(IN) :: geo
634  LOGICAL :: isvalid
635  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_Geometry_IsValid'
636  CHARACTER(ML) :: msg
637 
638  ! Setup
639  isvalid = .true.
640 
641  ! Field of view index (1-nFOV)
642  IF ( geo%iFOV < 0 ) THEN
643  msg = 'Invalid FOV index. Must be > 0.'
644  CALL display_message( routine_name, trim(msg), information )
645  isvalid = .false.
646  END IF
647 
648  ! Earth location
649  IF ( geo%Longitude < zero .OR. geo%Longitude > 360.0_fp ) THEN
650  msg = 'Invalid longitude. Must be degrees East (0->360)'
651  CALL display_message( routine_name, trim(msg), information )
652  isvalid = .false.
653  END IF
654  IF ( geo%Latitude < -90.0_fp .OR. geo%Latitude > 90.0_fp ) THEN
655  msg = 'Invalid latitude. Must be degrees North (-90->+90)'
656  CALL display_message( routine_name, trim(msg), information )
657  isvalid = .false.
658  END IF
659  IF ( geo%Surface_Altitude < min_surface_altitude .OR. &
660  geo%Surface_Altitude > max_surface_altitude ) THEN
661  WRITE(msg,'("Invalid surface altitude. Must be metres (",f6.1,"->+",f6.1,")")') &
663  CALL display_message( routine_name, trim(msg), information )
664  isvalid = .false.
665  END IF
666 
667  ! Sensor angles
668  IF ( abs(geo%Sensor_Scan_Angle) > max_sensor_scan_angle ) THEN
669  WRITE(msg,'("Invalid sensor scan angle. Must be |thetas(i)|<=",f4.1)') &
671  CALL display_message( routine_name, trim(msg), information )
672  isvalid = .false.
673  END IF
674  IF ( abs(geo%Sensor_Zenith_Angle) > max_sensor_zenith_angle ) THEN
675  WRITE(msg,'("Invalid sensor zenith angle. Must be |thetaz(i)|<=",f4.1)') &
677  CALL display_message( routine_name, trim(msg), information )
678  isvalid = .false.
679  END IF
680 ! IF ( geo%Sensor_Azimuth_Angle < ZERO .OR. &
681 ! geo%Sensor_Azimuth_Angle > MAX_SENSOR_AZIMUTH_ANGLE ) THEN
682 ! WRITE(msg,'("Invalid sensor azimuth angle. Must be 0<=phi(i)<=",f5.1)') &
683 ! MAX_SENSOR_AZIMUTH_ANGLE
684 ! CALL Display_Message( ROUTINE_NAME, TRIM(msg), INFORMATION )
685 ! IsValid = .FALSE.
686 ! END IF
687 
688  ! Source angle information
689  IF ( abs(geo%Source_Zenith_Angle) > 180.0_fp ) THEN
690  msg = 'Invalid source zenith angle. Must be |thetaz(s)|<=180.0'
691  CALL display_message( routine_name, trim(msg), information )
692  isvalid = .false.
693  END IF
694  IF ( geo%Source_Azimuth_Angle < zero .OR. &
695  geo%Source_Azimuth_Angle > max_source_azimuth_angle ) THEN
696  WRITE(msg,'("Invalid source azimuth angle. Must be 0<=phi(s)<=",f5.1)') &
698  CALL display_message( routine_name, trim(msg), information )
699  isvalid = .false.
700  END IF
701 
702  ! Flux angle information
703  IF ( abs(geo%Flux_Zenith_Angle) > max_flux_zenith_angle ) THEN
704  WRITE(msg,'("Invalid flux zenith angle. Must be |thetaz(f)|<=",f4.1)') &
706  CALL display_message( routine_name, trim(msg), information )
707  isvalid = .false.
708  END IF
709 
710  ! Date information
711  IF ( geo%Year < min_year ) THEN
712  WRITE(msg,'("Invalid year. Must be > ",i0)') min_year
713  CALL display_message( routine_name, trim(msg), information )
714  isvalid = .false.
715  END IF
716  IF ( geo%Month < 1 .OR. geo%Month > 12 ) THEN
717  CALL display_message( routine_name, 'Invalid month-of-year.', information )
718  isvalid = .false.
719  END IF
720  ! ...Only test Day value if Month and Year are valid
721  IF ( isvalid ) THEN
722  IF ( geo%Day < 1 .OR. geo%Day > daysinmonth(geo%Month,geo%Year) ) THEN
723  CALL display_message( routine_name, 'Invalid day-of-month.', information )
724  isvalid = .false.
725  END IF
726  END IF
727 
728  END FUNCTION crtm_geometry_isvalid
729 
730 
731 !--------------------------------------------------------------------------------
732 !:sdoc+:
733 !
734 ! NAME:
735 ! CRTM_Geometry_Inspect
736 !
737 ! PURPOSE:
738 ! Subroutine to print the contents of a CRTM Geometry object to stdout.
739 !
740 ! CALLING SEQUENCE:
741 ! CALL CRTM_Geometry_Inspect( Geo, Unit=unit )
742 !
743 ! INPUTS:
744 ! Geo: CRTM Geometry object to display.
745 ! UNITS: N/A
746 ! TYPE: CRTM_Geometry_type
747 ! DIMENSION: Scalar
748 ! ATTRIBUTES: INTENT(IN)
749 !
750 ! OPTIONAL INPUTS:
751 ! Unit: Unit number for an already open file to which the output
752 ! will be written.
753 ! If the argument is specified and the file unit is not
754 ! connected, the output goes to stdout.
755 ! UNITS: N/A
756 ! TYPE: INTEGER
757 ! DIMENSION: Scalar
758 ! ATTRIBUTES: INTENT(IN), OPTIONAL
759 !
760 !:sdoc-:
761 !--------------------------------------------------------------------------------
762 
763  SUBROUTINE crtm_geometry_inspect( geo, Unit )
764  ! Arguments
765  TYPE(crtm_geometry_type), INTENT(IN) :: geo
766  INTEGER, OPTIONAL, INTENT(IN) :: unit
767  ! Local parameters
768  CHARACTER(*), PARAMETER :: rfmt = 'es13.6'
769  ! Local variables
770  INTEGER :: fid
771 
772  ! Setup
773  fid = output_unit
774  IF ( PRESENT(unit) ) THEN
775  IF ( file_open(unit) ) fid = unit
776  END IF
777 
778 
779  WRITE(fid, '(1x,"Geometry OBJECT")')
780  ! Field of view index
781  WRITE(fid, '(3x,"FOV index :",1x,i0)') geo%iFOV
782  ! Earth location
783  WRITE(fid, '(3x,"Longitude :",1x,'//rfmt//')') geo%Longitude
784  WRITE(fid, '(3x,"Latitude :",1x,'//rfmt//')') geo%Latitude
785  WRITE(fid, '(3x,"Surface altitude :",1x,'//rfmt//')') geo%Surface_Altitude
786  ! Sensor angle information
787  WRITE(fid, '(3x,"Sensor scan angle :",1x,'//rfmt//')') geo%Sensor_Scan_Angle
788  WRITE(fid, '(3x,"Sensor zenith angle :",1x,'//rfmt//')') geo%Sensor_Zenith_Angle
789  WRITE(fid, '(3x,"Sensor azimuth angle:",1x,'//rfmt//')') geo%Sensor_Azimuth_Angle
790  ! Source angle information
791  WRITE(fid, '(3x,"Source zenith angle :",1x,'//rfmt//')') geo%Source_Zenith_Angle
792  WRITE(fid, '(3x,"Source azimuth angle:",1x,'//rfmt//')') geo%Source_Azimuth_Angle
793  ! Flux angle information
794  WRITE(fid, '(3x,"Flux zenith angle :",1x,'//rfmt//')') geo%Flux_Zenith_Angle
795  ! Date information
796  WRITE(fid, '(3x,"Year :",1x,i4)') geo%Year
797  WRITE(fid, '(3x,"Month :",1x,i4)') geo%Month
798  WRITE(fid, '(3x,"Day :",1x,i4)') geo%Day
799 
800  END SUBROUTINE crtm_geometry_inspect
801 
802 
803 !--------------------------------------------------------------------------------
804 !:sdoc+:
805 !
806 ! NAME:
807 ! CRTM_Geometry_DefineVersion
808 !
809 ! PURPOSE:
810 ! Subroutine to return the module version information.
811 !
812 ! CALLING SEQUENCE:
813 ! CALL CRTM_Geometry_DefineVersion( Id )
814 !
815 ! OUTPUT ARGUMENTS:
816 ! Id: Character string containing the version Id information
817 ! for the module.
818 ! UNITS: N/A
819 ! TYPE: CHARACTER(*)
820 ! DIMENSION: Scalar
821 ! ATTRIBUTES: INTENT(OUT)
822 !
823 !:sdoc-:
824 !--------------------------------------------------------------------------------
825 
826  SUBROUTINE crtm_geometry_defineversion( Id )
827  CHARACTER(*), INTENT(OUT) :: id
828  id = module_version_id
829  END SUBROUTINE crtm_geometry_defineversion
830 
831 
832 !------------------------------------------------------------------------------
833 !:sdoc+:
834 ! NAME:
835 ! CRTM_Geometry_Compare
836 !
837 ! PURPOSE:
838 ! Elemental function to compare two CRTM_Geometry objects to within
839 ! a user specified number of significant figures.
840 !
841 ! CALLING SEQUENCE:
842 ! is_comparable = CRTM_Geometry_Compare( x, y, n_SigFig=n_SigFig )
843 !
844 ! OBJECTS:
845 ! x, y: Two CRTM Geometry objects to be compared.
846 ! UNITS: N/A
847 ! TYPE: CRTM_Geometry_type
848 ! DIMENSION: Scalar or any rank
849 ! ATTRIBUTES: INTENT(IN)
850 !
851 ! OPTIONAL INPUTS:
852 ! n_SigFig: Number of significant figure to compare floating point
853 ! components.
854 ! UNITS: N/A
855 ! TYPE: INTEGER
856 ! DIMENSION: Scalar or same as input
857 ! ATTRIBUTES: INTENT(IN), OPTIONAL
858 !
859 ! FUNCTION RESULT:
860 ! is_equal: Logical value indicating whether the inputs are equal.
861 ! UNITS: N/A
862 ! TYPE: LOGICAL
863 ! DIMENSION: Same as inputs.
864 !:sdoc-:
865 !------------------------------------------------------------------------------
866 
867  ELEMENTAL FUNCTION crtm_geometry_compare( &
868  x, &
869  y, &
870  n_SigFig ) &
871  result( is_comparable )
872  ! Arguments
873  TYPE(crtm_geometry_type), INTENT(IN) :: x, y
874  INTEGER, OPTIONAL, INTENT(IN) :: n_sigfig
875  ! Function result
876  LOGICAL :: is_comparable
877  ! Variables
878  INTEGER :: n
879 
880  ! Set up
881  is_comparable = .false.
882  IF ( PRESENT(n_sigfig) ) THEN
883  n = abs(n_sigfig)
884  ELSE
885  n = default_n_sigfig
886  END IF
887 
888  ! Check the structure association status
889  IF ( (.NOT. crtm_geometry_associated(x)) .OR. &
890  (.NOT. crtm_geometry_associated(y)) ) RETURN
891 
892  ! Check scalars
893  IF ( (x%iFOV /= y%iFOV) .OR. &
894  (.NOT. compares_within_tolerance(x%Longitude , y%Longitude , n)) .OR. &
895  (.NOT. compares_within_tolerance(x%Latitude , y%Latitude , n)) .OR. &
896  (.NOT. compares_within_tolerance(x%Surface_Altitude , y%Surface_Altitude , n)) .OR. &
897  (.NOT. compares_within_tolerance(x%Sensor_Scan_Angle , y%Sensor_Scan_Angle , n)) .OR. &
898  (.NOT. compares_within_tolerance(x%Sensor_Zenith_Angle , y%Sensor_Zenith_Angle , n)) .OR. &
899  (.NOT. compares_within_tolerance(x%Sensor_Azimuth_Angle, y%Sensor_Azimuth_Angle, n)) .OR. &
900  (.NOT. compares_within_tolerance(x%Source_Zenith_Angle , y%Source_Zenith_Angle , n)) .OR. &
901  (.NOT. compares_within_tolerance(x%Source_Azimuth_Angle, y%Source_Azimuth_Angle, n)) .OR. &
902  (.NOT. compares_within_tolerance(x%Flux_Zenith_Angle , y%Flux_Zenith_Angle , n)) .OR. &
903  (x%Year /= y%Year ) .OR. &
904  (x%Month /= y%Month) .OR. &
905  (x%Day /= y%Day ) ) RETURN
906 
907  ! If we get here, the structures are comparable
908  is_comparable = .true.
909 
910  END FUNCTION crtm_geometry_compare
911 
912 
913 !------------------------------------------------------------------------------
914 !:sdoc+:
915 !
916 ! NAME:
917 ! CRTM_Geometry_InquireFile
918 !
919 ! PURPOSE:
920 ! Function to inquire CRTM Geometry object files.
921 !
922 ! CALLING SEQUENCE:
923 ! Error_Status = CRTM_Geometry_InquireFile( Filename , &
924 ! n_Profiles = n_Profiles )
925 !
926 ! INPUTS:
927 ! Filename: Character string specifying the name of a
928 ! CRTM Geometry data file to read.
929 ! UNITS: N/A
930 ! TYPE: CHARACTER(*)
931 ! DIMENSION: Scalar
932 ! ATTRIBUTES: INTENT(IN)
933 !
934 ! OPTIONAL OUTPUTS:
935 ! n_Profiles: The number of profiles for which their is geometry
936 ! information in the data file.
937 ! UNITS: N/A
938 ! TYPE: INTEGER
939 ! DIMENSION: Scalar
940 ! ATTRIBUTES: OPTIONAL, INTENT(OUT)
941 !
942 ! FUNCTION RESULT:
943 ! Error_Status: The return value is an integer defining the error status.
944 ! The error codes are defined in the Message_Handler module.
945 ! If == SUCCESS, the file inquire was successful
946 ! == FAILURE, an unrecoverable error occurred.
947 ! UNITS: N/A
948 ! TYPE: INTEGER
949 ! DIMENSION: Scalar
950 !
951 !:sdoc-:
952 !------------------------------------------------------------------------------
953 
954  FUNCTION crtm_geometry_inquirefile( &
955  Filename , & ! Input
956  n_Profiles) & ! Optional output
957  result( err_stat )
958  ! Arguments
959  CHARACTER(*), INTENT(IN) :: filename
960  INTEGER , OPTIONAL, INTENT(OUT) :: n_profiles
961  ! Function result
962  INTEGER :: err_stat
963  ! Function parameters
964  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_Geometry_InquireFile'
965  ! Function variables
966  CHARACTER(ML) :: msg
967  CHARACTER(ML) :: io_msg
968  INTEGER :: io_stat
969  INTEGER :: fid
970  INTEGER :: m
971 
972  ! Set up
973  err_stat = success
974  ! ...Check that the file exists
975  IF ( .NOT. file_exists( trim(filename) ) ) THEN
976  msg = 'File '//trim(filename)//' not found.'
977  CALL inquire_cleanup(); RETURN
978  END IF
979 
980 
981  ! Open the file
982  err_stat = open_binary_file( filename, fid )
983  IF ( err_stat /= success ) THEN
984  msg = 'Error opening '//trim(filename)
985  CALL inquire_cleanup(); RETURN
986  END IF
987 
988 
989  ! Read the number of profiles
990  READ( fid,iostat=io_stat,iomsg=io_msg ) m
991  IF ( io_stat /= 0 ) THEN
992  msg = 'Error reading data dimension from '//trim(filename)//' - '//trim(io_msg)
993  CALL inquire_cleanup(); RETURN
994  END IF
995 
996 
997  ! Close the file
998  CLOSE( fid,iostat=io_stat,iomsg=io_msg )
999  IF ( io_stat /= 0 ) THEN
1000  msg = 'Error closing '//trim(filename)//' - '//trim(io_msg)
1001  CALL inquire_cleanup(); RETURN
1002  END IF
1003 
1004 
1005  ! Set the return arguments
1006  IF ( PRESENT(n_profiles) ) n_profiles = m
1007 
1008  CONTAINS
1009 
1010  SUBROUTINE inquire_cleanup()
1011  IF ( file_open(fid) ) THEN
1012  CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1013  IF ( io_stat /= success ) &
1014  msg = trim(msg)//'; Error closing input file during error cleanup - '//trim(io_msg)
1015  END IF
1016  err_stat = failure
1017  CALL display_message( routine_name, msg, err_stat )
1018  END SUBROUTINE inquire_cleanup
1019 
1020  END FUNCTION crtm_geometry_inquirefile
1021 
1022 
1023 !------------------------------------------------------------------------------
1024 !:sdoc+:
1025 !
1026 ! NAME:
1027 ! CRTM_Geometry_ReadFile
1028 !
1029 ! PURPOSE:
1030 ! Function to read CRTM Geometry object files.
1031 !
1032 ! CALLING SEQUENCE:
1033 ! Error_Status = CRTM_Geometry_ReadFile( Filename , &
1034 ! Geometry , &
1035 ! Quiet = Quiet , &
1036 ! No_Close = No_Close , &
1037 ! n_Profiles = n_Profiles )
1038 !
1039 ! INPUTS:
1040 ! Filename: Character string specifying the name of an
1041 ! a Geometry data file to read.
1042 ! UNITS: N/A
1043 ! TYPE: CHARACTER(*)
1044 ! DIMENSION: Scalar
1045 ! ATTRIBUTES: INTENT(IN)
1046 !
1047 ! OUTPUTS:
1048 ! Geometry: CRTM Geometry object array containing the
1049 ! data read from file.
1050 ! UNITS: N/A
1051 ! TYPE: CRTM_Geometry_type
1052 ! DIMENSION: Rank-1
1053 ! ATTRIBUTES: INTENT(OUT), ALLOCATABLE
1054 !
1055 ! OPTIONAL INPUTS:
1056 ! Quiet: Set this logical argument to suppress INFORMATION
1057 ! messages being printed to stdout
1058 ! If == .FALSE., INFORMATION messages are OUTPUT [DEFAULT].
1059 ! == .TRUE., INFORMATION messages are SUPPRESSED.
1060 ! If not specified, default is .FALSE.
1061 ! UNITS: N/A
1062 ! TYPE: LOGICAL
1063 ! DIMENSION: Scalar
1064 ! ATTRIBUTES: INTENT(IN), OPTIONAL
1065 !
1066 ! No_Close: Set this logical argument to NOT close the file upon exit.
1067 ! If == .FALSE., the input file is closed upon exit [DEFAULT]
1068 ! == .TRUE., the input file is NOT closed upon exit.
1069 ! If not specified, default is .FALSE.
1070 ! UNITS: N/A
1071 ! TYPE: LOGICAL
1072 ! DIMENSION: Scalar
1073 ! ATTRIBUTES: INTENT(IN), OPTIONAL
1074 !
1075 ! OPTIONAL OUTPUTS:
1076 ! n_Profiles: The number of profiles for which data was read.
1077 ! UNITS: N/A
1078 ! TYPE: INTEGER
1079 ! DIMENSION: Scalar
1080 ! ATTRIBUTES: OPTIONAL, INTENT(OUT)
1081 !
1082 ! FUNCTION RESULT:
1083 ! Error_Status: The return value is an integer defining the error status.
1084 ! The error codes are defined in the Message_Handler module.
1085 ! If == SUCCESS, the file read was successful
1086 ! == FAILURE, an unrecoverable error occurred.
1087 ! UNITS: N/A
1088 ! TYPE: INTEGER
1089 ! DIMENSION: Scalar
1090 !
1091 !:sdoc-:
1092 !------------------------------------------------------------------------------
1093 
1094  FUNCTION crtm_geometry_readfile( &
1095  Filename , & ! Input
1096  Geometry , & ! Output
1097  Quiet , & ! Optional input
1098  No_Close , & ! Optional input
1099  n_Profiles, & ! Optional output
1100  Debug ) & ! Optional input (Debug output control)
1101  result( err_stat )
1102  ! Arguments
1103  CHARACTER(*), INTENT(IN) :: filename
1104  TYPE(crtm_geometry_type), ALLOCATABLE, INTENT(OUT) :: geometry(:)
1105  LOGICAL, OPTIONAL, INTENT(IN) :: quiet
1106  LOGICAL, OPTIONAL, INTENT(IN) :: no_close
1107  INTEGER, OPTIONAL, INTENT(OUT) :: n_profiles
1108  LOGICAL, OPTIONAL, INTENT(IN) :: debug
1109  ! Function result
1110  INTEGER :: err_stat
1111  ! Function parameters
1112  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_Geometry_ReadFile'
1113  ! Function variables
1114  CHARACTER(ML) :: msg
1115  CHARACTER(ML) :: io_msg
1116  CHARACTER(ML) :: alloc_msg
1117  INTEGER :: io_stat
1118  INTEGER :: alloc_stat
1119  LOGICAL :: noisy
1120  LOGICAL :: yes_close
1121  INTEGER :: fid
1122  INTEGER :: m, n_input_profiles
1123 
1124 
1125  ! Set up
1126  err_stat = success
1127  ! ...Check Quiet argument
1128  noisy = .true.
1129  IF ( PRESENT(quiet) ) noisy = .NOT. quiet
1130  ! ...Check file close argument
1131  yes_close = .true.
1132  IF ( PRESENT(no_close) ) yes_close = .NOT. no_close
1133  ! ...Override Quiet settings if debug set.
1134  IF ( PRESENT(debug) ) noisy = debug
1135 
1136 
1137  ! Check if the file is open
1138  IF ( file_open( filename ) ) THEN
1139  ! Yes, the file is already open
1140  ! ...Get the file id
1141  INQUIRE( file=filename,number=fid )
1142  IF ( fid == -1 ) THEN
1143  msg = 'Error inquiring '//trim(filename)//' for its unit number'
1144  CALL read_cleanup(); RETURN
1145  END IF
1146  ELSE
1147  ! No, the file is not open
1148  ! ...Check that the file exists
1149  IF ( .NOT. file_exists( filename ) ) THEN
1150  msg = 'File '//trim(filename)//' not found.'
1151  CALL read_cleanup(); RETURN
1152  END IF
1153  ! ...Open the file
1154  err_stat = open_binary_file( filename, fid )
1155  IF ( err_stat /= success ) THEN
1156  msg = 'Error opening '//trim(filename)
1157  CALL read_cleanup(); RETURN
1158  END IF
1159  END IF
1160 
1161 
1162  ! Read the dimensions
1163  READ( fid,iostat=io_stat,iomsg=io_msg ) n_input_profiles
1164  IF ( io_stat /= 0 ) THEN
1165  msg = 'Error reading dimension from '//trim(filename)//' - '//trim(io_msg)
1166  CALL read_cleanup(); RETURN
1167  END IF
1168  ! ...Allocate the return structure array
1169  ALLOCATE(geometry(n_input_profiles), stat=alloc_stat, errmsg=alloc_msg)
1170  IF ( alloc_stat /= 0 ) THEN
1171  msg = 'Error allocating Geometry array - '//trim(alloc_msg)
1172  CALL read_cleanup(); RETURN
1173  END IF
1174 
1175 
1176  ! Read the geometry data
1177  geometry_loop: DO m = 1, n_input_profiles
1178  err_stat = crtm_geometry_readrecord( fid, geometry(m) )
1179  IF ( err_stat /= success ) THEN
1180  WRITE( msg,'("Error reading Geometry element #",i0," from ",a)' ) m, trim(filename)
1181  CALL read_cleanup(); RETURN
1182  END IF
1183  END DO geometry_loop
1184 
1185 
1186  ! Close the file
1187  IF ( yes_close ) THEN
1188  CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1189  IF ( io_stat /= 0 ) THEN
1190  msg = 'Error closing '//trim(filename)//' - '//trim(io_msg)
1191  CALL read_cleanup(); RETURN
1192  END IF
1193  END IF
1194 
1195 
1196  ! Set the return values
1197  IF ( PRESENT(n_profiles) ) n_profiles = n_input_profiles
1198 
1199 
1200  ! Output an info message
1201  IF ( noisy ) THEN
1202  WRITE( msg,'("Number of Geometry entries read from ",a,": ",i0)' ) &
1203  trim(filename), n_input_profiles
1204  CALL display_message( routine_name, msg, information )
1205  END IF
1206 
1207  CONTAINS
1208 
1209  SUBROUTINE read_cleanup()
1210  IF ( file_open(fid) ) THEN
1211  CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1212  IF ( io_stat /= 0 ) &
1213  msg = trim(msg)//'; Error closing input file during error cleanup - '//trim(io_msg)
1214  END IF
1215  IF ( ALLOCATED(geometry) ) THEN
1216  DEALLOCATE(geometry, stat=alloc_stat, errmsg=alloc_msg)
1217  IF ( alloc_stat /= 0 ) &
1218  msg = trim(msg)//'; Error deallocating Geometry array during error cleanup - '//&
1219  trim(alloc_msg)
1220  END IF
1221  err_stat = failure
1222  CALL display_message( routine_name, msg, err_stat )
1223  END SUBROUTINE read_cleanup
1224 
1225  END FUNCTION crtm_geometry_readfile
1226 
1227 
1228 !------------------------------------------------------------------------------
1229 !:sdoc+:
1230 !
1231 ! NAME:
1232 ! CRTM_Geometry_WriteFile
1233 !
1234 ! PURPOSE:
1235 ! Function to write CRTM Geometry object files.
1236 !
1237 ! CALLING SEQUENCE:
1238 ! Error_Status = CRTM_Geometry_WriteFile( Filename , &
1239 ! Geometry , &
1240 ! Quiet = Quiet , &
1241 ! No_Close = No_Close )
1242 !
1243 ! INPUTS:
1244 ! Filename: Character string specifying the name of the
1245 ! Geometry format data file to write.
1246 ! UNITS: N/A
1247 ! TYPE: CHARACTER(*)
1248 ! DIMENSION: Scalar
1249 ! ATTRIBUTES: INTENT(IN)
1250 !
1251 ! Geometry: CRTM Geometry object array containing the Geometry
1252 ! data to write.
1253 ! UNITS: N/A
1254 ! TYPE: CRTM_Geometry_type
1255 ! DIMENSION: Rank-1
1256 ! ATTRIBUTES: INTENT(IN)
1257 !
1258 ! OPTIONAL INPUTS:
1259 ! Quiet: Set this logical argument to suppress INFORMATION
1260 ! messages being printed to stdout
1261 ! If == .FALSE., INFORMATION messages are OUTPUT [DEFAULT].
1262 ! == .TRUE., INFORMATION messages are SUPPRESSED.
1263 ! If not specified, default is .FALSE.
1264 ! UNITS: N/A
1265 ! TYPE: LOGICAL
1266 ! DIMENSION: Scalar
1267 ! ATTRIBUTES: INTENT(IN), OPTIONAL
1268 !
1269 ! No_Close: Set this logical argument to NOT close the file upon exit.
1270 ! If == .FALSE., the input file is closed upon exit [DEFAULT]
1271 ! == .TRUE., the input file is NOT closed upon exit.
1272 ! If not specified, default is .FALSE.
1273 ! UNITS: N/A
1274 ! TYPE: LOGICAL
1275 ! DIMENSION: Scalar
1276 ! ATTRIBUTES: INTENT(IN), OPTIONAL
1277 !
1278 ! FUNCTION RESULT:
1279 ! Error_Status: The return value is an integer defining the error status.
1280 ! The error codes are defined in the Message_Handler module.
1281 ! If == SUCCESS, the file write was successful
1282 ! == FAILURE, an unrecoverable error occurred.
1283 ! UNITS: N/A
1284 ! TYPE: INTEGER
1285 ! DIMENSION: Scalar
1286 !
1287 ! SIDE EFFECTS:
1288 ! - If the output file already exists, it is overwritten.
1289 ! - If an error occurs during *writing*, the output file is deleted before
1290 ! returning to the calling routine.
1291 !
1292 !:sdoc-:
1293 !------------------------------------------------------------------------------
1294 
1295  FUNCTION crtm_geometry_writefile( &
1296  Filename, & ! Input
1297  Geometry, & ! Input
1298  Quiet , & ! Optional input
1299  No_Close, & ! Optional input
1300  Debug ) & ! Optional input (Debug output control)
1301  result( err_stat )
1302  ! Arguments
1303  CHARACTER(*), INTENT(IN) :: filename
1304  TYPE(crtm_geometry_type), INTENT(IN) :: geometry(:)
1305  LOGICAL, OPTIONAL, INTENT(IN) :: quiet
1306  LOGICAL, OPTIONAL, INTENT(IN) :: no_close
1307  LOGICAL, OPTIONAL, INTENT(IN) :: debug
1308  ! Function result
1309  INTEGER :: err_stat
1310  ! Function parameters
1311  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_Geometry_WriteFile'
1312  ! Function variables
1313  CHARACTER(ML) :: msg
1314  CHARACTER(ML) :: io_msg
1315  INTEGER :: io_stat
1316  LOGICAL :: noisy
1317  LOGICAL :: yes_close
1318  INTEGER :: fid
1319  INTEGER :: m, ng
1320 
1321  ! Set up
1322  err_stat = success
1323  ! ...Check Quiet argument
1324  noisy = .true.
1325  IF ( PRESENT(quiet) ) noisy = .NOT. quiet
1326  ! ...Check file close argument
1327  yes_close = .true.
1328  IF ( PRESENT(no_close) ) yes_close = .NOT. no_close
1329  ! ...Override Quiet settings if debug set.
1330  IF ( PRESENT(debug) ) noisy = debug
1331 
1332 
1333  ! Check if the file is open
1334  IF ( file_open( filename ) ) THEN
1335  ! Yes, the file is already open
1336  INQUIRE( file=filename,number=fid )
1337  IF ( fid == -1 ) THEN
1338  msg = 'Error inquiring '//trim(filename)//' for its unit number'
1339  CALL write_cleanup(); RETURN
1340  END IF
1341  ELSE
1342  ! No, the file is not open
1343  err_stat = open_binary_file( filename, fid, for_output = .true. )
1344  IF ( err_stat /= success ) THEN
1345  msg = 'Error opening '//trim(filename)
1346  CALL write_cleanup(); RETURN
1347  END IF
1348  END IF
1349 
1350 
1351  ! Write the dimensions
1352  ng = SIZE(geometry)
1353  WRITE( fid,iostat=io_stat,iomsg=io_msg ) ng
1354  IF ( io_stat /= 0 ) THEN
1355  msg = 'Error writing data dimension to '//trim(filename)//'- '//trim(io_msg)
1356  CALL write_cleanup(); RETURN
1357  END IF
1358 
1359 
1360  ! Write the data
1361  geometry_loop: DO m = 1, ng
1362  err_stat = crtm_geometry_writerecord( fid, geometry(m) )
1363  IF ( err_stat /= success ) THEN
1364  WRITE( msg,'("Error writing Geometry element #",i0," to ",a)' ) m, trim(filename)
1365  CALL write_cleanup(); RETURN
1366  END IF
1367  END DO geometry_loop
1368 
1369 
1370  ! Close the file (if error, no delete)
1371  IF ( yes_close ) THEN
1372  CLOSE( fid,status='KEEP',iostat=io_stat,iomsg=io_msg )
1373  IF ( io_stat /= 0 ) THEN
1374  msg = 'Error closing '//trim(filename)//'- '//trim(io_msg)
1375  CALL write_cleanup(); RETURN
1376  END IF
1377  END IF
1378 
1379 
1380  ! Output an info message
1381  IF ( noisy ) THEN
1382  WRITE( msg,'("Number of geometry entries written to ",a,": ",i0)' ) trim(filename), ng
1383  CALL display_message( routine_name, msg, information )
1384  END IF
1385 
1386  CONTAINS
1387 
1388  SUBROUTINE write_cleanup()
1389  IF ( file_open(fid) ) THEN
1390  CLOSE( fid,status=write_error_status,iostat=io_stat,iomsg=io_msg )
1391  IF ( io_stat /= 0 ) &
1392  msg = trim(msg)//'; Error deleting output file during error cleanup - '//trim(io_msg)
1393  END IF
1394  err_stat = failure
1395  CALL display_message( routine_name, msg, err_stat )
1396  END SUBROUTINE write_cleanup
1397 
1398  END FUNCTION crtm_geometry_writefile
1399 
1400 
1401 !----------------------------------------------------------------------------------
1402 !:sdoc+:
1403 !
1404 ! NAME:
1405 ! CRTM_Geometry_ReadRecord
1406 !
1407 ! PURPOSE:
1408 ! Utility function to read a single Geometry data record
1409 !
1410 ! CALLING SEQUENCE:
1411 ! Error_Status = CRTM_Geometry_ReadRecord( FileID, Geometry )
1412 !
1413 ! INPUTS:
1414 ! FileID: Logical unit number from which to read data.
1415 ! UNITS: N/A
1416 ! TYPE: INTEGER
1417 ! DIMENSION: Scalar
1418 ! ATTRIBUTES: INTENT(IN)
1419 !
1420 ! OUTPUTS:
1421 ! Geometry: CRTM Geometry object containing the data read in.
1422 ! UNITS: N/A
1423 ! TYPE: CRTM_Geometry_type
1424 ! DIMENSION: Scalar
1425 ! ATTRIBUTES: INTENT(OUT)
1426 !
1427 ! FUNCTION RESULT:
1428 ! Error_Status: The return value is an integer defining the error status.
1429 ! The error codes are defined in the Message_Handler module.
1430 ! If == SUCCESS, the read was successful
1431 ! == FAILURE, an unrecoverable error occurred.
1432 ! UNITS: N/A
1433 ! TYPE: INTEGER
1434 ! DIMENSION: Scalar
1435 !:sdoc-:
1436 !----------------------------------------------------------------------------------
1437 
1438  FUNCTION crtm_geometry_readrecord( fid, geo ) RESULT( err_stat )
1439  ! Arguments
1440  INTEGER, INTENT(IN) :: fid
1441  TYPE(crtm_geometry_type), INTENT(OUT) :: geo
1442  ! Function result
1443  INTEGER :: err_stat
1444  ! Function parameters
1445  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_Geometry_ReadRecord'
1446  ! Function variables
1447  CHARACTER(ML) :: msg
1448  CHARACTER(ML) :: io_msg
1449  INTEGER :: io_stat
1450 
1451  ! Set up
1452  err_stat = success
1453 
1454  ! Read the data record
1455  READ( fid,iostat=io_stat,iomsg=io_msg ) &
1456  geo%iFOV , &
1457  geo%Longitude , &
1458  geo%Latitude , &
1459  geo%Surface_Altitude , &
1460  geo%Sensor_Scan_Angle , &
1461  geo%Sensor_Zenith_Angle , &
1462  geo%Sensor_Azimuth_Angle, &
1463  geo%Source_Zenith_Angle , &
1464  geo%Source_Azimuth_Angle, &
1465  geo%Flux_Zenith_Angle , &
1466  geo%Year , &
1467  geo%Month , &
1468  geo%Day
1469 
1470  IF ( io_stat /= 0 ) THEN
1471  msg = 'Error reading Geometry data - '//trim(io_msg)
1472  CALL read_record_cleanup(); RETURN
1473  END IF
1474 
1475  CONTAINS
1476 
1477  SUBROUTINE read_record_cleanup()
1479  CLOSE( fid,iostat=io_stat,iomsg=io_msg )
1480  IF ( io_stat /= success ) &
1481  msg = trim(msg)//'; Error closing file during error cleanup - '//trim(io_msg)
1482  err_stat = failure
1483  CALL display_message( routine_name, msg, err_stat )
1484  END SUBROUTINE read_record_cleanup
1485 
1486  END FUNCTION crtm_geometry_readrecord
1487 
1488 
1489 !----------------------------------------------------------------------------------
1490 !:sdoc+:
1491 !
1492 ! NAME:
1493 ! CRTM_Geometry_WriteRecord
1494 !
1495 ! PURPOSE:
1496 ! Function to write a single Geometry data record
1497 !
1498 ! CALLING SEQUENCE:
1499 ! Error_Status = CRTM_Geometry_WriteRecord( FileID, Geometry )
1500 !
1501 ! INPUTS:
1502 ! FileID: Logical unit number to which data is written
1503 ! UNITS: N/A
1504 ! TYPE: INTEGER
1505 ! DIMENSION: Scalar
1506 ! ATTRIBUTES: INTENT(IN)
1507 !
1508 ! Geometry: CRTM Geometry object containing the data to write.
1509 ! UNITS: N/A
1510 ! TYPE: CRTM_Geometry_type
1511 ! DIMENSION: Scalar
1512 ! ATTRIBUTES: INTENT(IN)
1513 !
1514 ! FUNCTION RESULT:
1515 ! Error_Status: The return value is an integer defining the error status.
1516 ! The error codes are defined in the Message_Handler module.
1517 ! If == SUCCESS the record write was successful
1518 ! == FAILURE an unrecoverable error occurred.
1519 ! UNITS: N/A
1520 ! TYPE: INTEGER
1521 ! DIMENSION: Scalar
1522 !:sdoc-:
1523 !----------------------------------------------------------------------------------
1524 
1525  FUNCTION crtm_geometry_writerecord( fid, geo ) RESULT( err_stat )
1526  ! Arguments
1527  INTEGER, INTENT(IN) :: fid
1528  TYPE(crtm_geometry_type), INTENT(IN) :: geo
1529  ! Function result
1530  INTEGER :: err_stat
1531  ! Function parameters
1532  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_Geometry_WriteRecord'
1533  ! Function variables
1534  CHARACTER(ML) :: msg
1535  CHARACTER(ML) :: io_msg
1536  INTEGER :: io_stat
1537 
1538  ! Set up
1539  err_stat = success
1540 
1541 
1542  ! Write the data record
1543  WRITE( fid,iostat=io_stat,iomsg=io_msg ) &
1544  geo%iFOV , &
1545  geo%Longitude , &
1546  geo%Latitude , &
1547  geo%Surface_Altitude , &
1548  geo%Sensor_Scan_Angle , &
1549  geo%Sensor_Zenith_Angle , &
1550  geo%Sensor_Azimuth_Angle, &
1551  geo%Source_Zenith_Angle , &
1552  geo%Source_Azimuth_Angle, &
1553  geo%Flux_Zenith_Angle , &
1554  geo%Year , &
1555  geo%Month , &
1556  geo%Day
1557  IF ( io_stat /= 0 ) THEN
1558  msg = 'Error writing Geometry data - '//trim(io_msg)
1559  CALL write_record_cleanup(); RETURN
1560  END IF
1561 
1562  CONTAINS
1563 
1564  SUBROUTINE write_record_cleanup()
1565  CLOSE( fid,status=write_error_status,iostat=io_stat,iomsg=io_msg )
1566  IF ( io_stat /= success ) &
1567  msg = trim(msg)//'; Error closing file during error cleanup - '//trim(io_msg)
1568  err_stat = failure
1569  CALL display_message( routine_name, msg, err_stat )
1570  END SUBROUTINE write_record_cleanup
1571 
1572  END FUNCTION crtm_geometry_writerecord
1573 
1574 
1575 !##################################################################################
1576 !##################################################################################
1577 !## ##
1578 !## ## PRIVATE MODULE ROUTINES ## ##
1579 !## ##
1580 !##################################################################################
1581 !##################################################################################
1582 
1583 !--------------------------------------------------------------------------------
1584 !
1585 ! NAME:
1586 ! CRTM_Geometry_Equal
1587 !
1588 ! PURPOSE:
1589 ! Elemental function to test the equality of two CRTM_Geometry objects.
1590 ! Used in OPERATOR(==) interface block.
1591 !
1592 ! CALLING SEQUENCE:
1593 ! is_equal = CRTM_Geometry_Equal( x, y )
1594 !
1595 ! or
1596 !
1597 ! IF ( x == y ) THEN
1598 ! ...
1599 ! END IF
1600 !
1601 ! OBJECTS:
1602 ! x, y: Two CRTM Geometry objects to be compared.
1603 ! UNITS: N/A
1604 ! TYPE: CRTM_Geometry_type
1605 ! DIMENSION: Scalar or any rank
1606 ! ATTRIBUTES: INTENT(IN)
1607 !
1608 ! FUNCTION RESULT:
1609 ! is_equal: Logical value indicating whether the inputs are equal.
1610 ! UNITS: N/A
1611 ! TYPE: LOGICAL
1612 ! DIMENSION: Same as inputs.
1613 !
1614 !--------------------------------------------------------------------------------
1615 
1616  ELEMENTAL FUNCTION crtm_geometry_equal( x, y ) RESULT( is_equal )
1617  TYPE(crtm_geometry_type) , INTENT(IN) :: x, y
1618  LOGICAL :: is_equal
1619 
1620  is_equal = ( (x%iFOV == y%iFOV ) .AND. &
1621  (x%Longitude .equalto. y%Longitude ) .AND. &
1622  (x%Latitude .equalto. y%Latitude ) .AND. &
1623  (x%Surface_Altitude .equalto. y%Surface_Altitude ) .AND. &
1624  (x%Sensor_Scan_Angle .equalto. y%Sensor_Scan_Angle ) .AND. &
1625  (x%Sensor_Zenith_Angle .equalto. y%Sensor_Zenith_Angle ) .AND. &
1626  (x%Sensor_Azimuth_Angle .equalto. y%Sensor_Azimuth_Angle) .AND. &
1627  (x%Source_Zenith_Angle .equalto. y%Source_Zenith_Angle ) .AND. &
1628  (x%Source_Azimuth_Angle .equalto. y%Source_Azimuth_Angle) .AND. &
1629  (x%Flux_Zenith_Angle .equalto. y%Flux_Zenith_Angle ) .AND. &
1630  (x%Year == y%Year ) .AND. &
1631  (x%Month == y%Month) .AND. &
1632  (x%Day == y%Day ) )
1633 
1634  END FUNCTION crtm_geometry_equal
1635 
1636 
1637 !--------------------------------------------------------------------------------
1638 !
1639 ! NAME:
1640 ! CRTM_Geometry_Subtract
1641 !
1642 ! PURPOSE:
1643 ! Elemental function to subtract two CRTM Geometry objects.
1644 ! Used in OPERATOR(-) interface block.
1645 !
1646 ! CALLING SEQUENCE:
1647 ! gdiff = CRTM_Geometry_Subtract( g1, g2 )
1648 !
1649 ! or
1650 !
1651 ! gsum = g1 - g2
1652 !
1653 !
1654 ! INPUTS:
1655 ! g1, g2: The Geometry objects to difference.
1656 ! UNITS: N/A
1657 ! TYPE: CRTM_Geometry_type
1658 ! DIMENSION: Scalar
1659 ! ATTRIBUTES: INTENT(IN OUT)
1660 !
1661 ! RESULT:
1662 ! gdiff: Geometry object containing the differenced components.
1663 ! UNITS: N/A
1664 ! TYPE: CRTM_Geometry_type
1665 ! DIMENSION: Scalar
1666 !
1667 !--------------------------------------------------------------------------------
1668 
1669  ELEMENTAL FUNCTION crtm_geometry_subtract( g1, g2 ) RESULT( gdiff )
1670  TYPE(crtm_geometry_type), INTENT(IN) :: g1, g2
1671  TYPE(crtm_geometry_type) :: gdiff
1672 
1673  ! Copy the first structure
1674  gdiff = g1
1675 
1676  ! And subtract the second one's components from it
1677  gdiff%iFOV = gdiff%iFOV - g2%iFOV
1678  gdiff%Longitude = gdiff%Longitude - g2%Longitude
1679  gdiff%Latitude = gdiff%Latitude - g2%Latitude
1680  gdiff%Surface_Altitude = gdiff%Surface_Altitude - g2%Surface_Altitude
1681  gdiff%Sensor_Scan_Angle = gdiff%Sensor_Scan_Angle - g2%Sensor_Scan_Angle
1682  gdiff%Sensor_Zenith_Angle = gdiff%Sensor_Zenith_Angle - g2%Sensor_Zenith_Angle
1683  gdiff%Sensor_Azimuth_Angle = gdiff%Sensor_Azimuth_Angle - g2%Sensor_Azimuth_Angle
1684  gdiff%Source_Zenith_Angle = gdiff%Source_Zenith_Angle - g2%Source_Zenith_Angle
1685  gdiff%Source_Azimuth_Angle = gdiff%Source_Azimuth_Angle - g2%Source_Azimuth_Angle
1686  gdiff%Flux_Zenith_Angle = gdiff%Flux_Zenith_Angle - g2%Flux_Zenith_Angle
1687  gdiff%Year = gdiff%Year - g2%Year
1688  gdiff%Month = gdiff%Month - g2%Month
1689  gdiff%Day = gdiff%Day - g2%Day
1690 
1691  END FUNCTION crtm_geometry_subtract
1692 
1693 END MODULE crtm_geometry_define
real(fp), parameter, public max_sensor_zenith_angle
real(fp), parameter, public diffusivity_angle
subroutine, public crtm_geometry_defineversion(Id)
integer, parameter, public failure
integer, parameter, public warning
integer function, public crtm_geometry_writefile(Filename, Geometry, Quiet, No_Close, Debug)
integer, parameter, public fp
Definition: Type_Kinds.f90:124
elemental subroutine, public crtm_geometry_getvalue(geo, iFOV, Longitude, Latitude, Surface_Altitude, Sensor_Scan_Angle, Sensor_Zenith_Angle, Sensor_Azimuth_Angle, Source_Zenith_Angle, Source_Azimuth_Angle, Flux_Zenith_Angle, Year, Month, Day)
integer function, public readgatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
elemental subroutine, public crtm_geometry_destroy(geo)
elemental logical function, public crtm_geometry_compare(x, y, n_SigFig)
real(fp), parameter zero
integer, parameter min_year
subroutine inquire_cleanup()
real(fp), parameter, public max_sensor_azimuth_angle
real(fp), parameter, public max_source_zenith_angle
subroutine read_cleanup()
character(*), parameter write_error_status
character(*), parameter module_version_id
subroutine write_cleanup()
subroutine read_record_cleanup()
integer function, public crtm_geometry_readrecord(fid, geo)
real(fp), parameter, public max_source_azimuth_angle
integer function, public open_binary_file(Filename, FileID, For_Output, No_Check)
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
real(fp), parameter, public max_flux_zenith_angle
subroutine, public crtm_geometry_inspect(geo, Unit)
logical function, public crtm_geometry_isvalid(geo)
elemental subroutine, public crtm_geometry_setvalue(geo, iFOV, Longitude, Latitude, Surface_Altitude, Sensor_Scan_Angle, Sensor_Zenith_Angle, Sensor_Azimuth_Angle, Source_Zenith_Angle, Source_Azimuth_Angle, Flux_Zenith_Angle, Year, Month, Day)
real(fp), parameter, public max_sensor_scan_angle
integer, parameter, public default_n_sigfig
elemental integer function, public daysinmonth(Month, Year)
real(fp), parameter, public min_surface_altitude
integer function, public writegatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
real(fp), parameter, public max_surface_altitude
elemental logical function, public crtm_geometry_associated(Geometry)
subroutine write_record_cleanup()
elemental type(crtm_geometry_type) function crtm_geometry_subtract(g1, g2)
elemental logical function crtm_geometry_equal(x, y)
integer function, public crtm_geometry_readfile(Filename, Geometry, Quiet, No_Close, n_Profiles, Debug)
integer function, public crtm_geometry_writerecord(fid, geo)
integer, parameter, public success
integer function, public crtm_geometry_inquirefile(Filename, n_Profiles)
integer, parameter, public information
elemental subroutine, public crtm_geometry_create(geo)