FV3 Bundle
SSU_Input_Define.f90
Go to the documentation of this file.
1 !
2 ! SSU_Input_Define
3 !
4 ! Module containing the structure definition and associated routines
5 ! for CRTM inputs specific to SSU
6 !
7 !
8 ! CREATION HISTORY:
9 ! Written by: Yong Han, NOAA/NESDIS, Oct 6, 2009
10 ! yong.han@noaa.gov
11 !
12 ! Paul van Delst, 20-Oct-2009
13 ! paul.vandelst@noaa.gov
14 !
15 
17 
18  ! -----------------
19  ! Environment setup
20  ! -----------------
21  ! Module use
22  USE type_kinds , ONLY: fp, long, double
24  USE compare_float_numbers, ONLY: OPERATOR(.equalto.)
29  ! ------------
30  ! Visibilities
31  ! ------------
32  PRIVATE
33  ! Datatypes
34  PUBLIC :: ssu_input_type
35  ! Operators
36  PUBLIC :: OPERATOR(==)
37  ! Procedures
38  PUBLIC :: ssu_input_isvalid
39  PUBLIC :: ssu_input_inspect
40  PUBLIC :: ssu_input_validrelease
41  PUBLIC :: ssu_input_defineversion
42  PUBLIC :: ssu_input_getvalue
43  PUBLIC :: ssu_input_setvalue
45  PUBLIC :: ssu_input_readfile
46  PUBLIC :: ssu_input_writefile
47 
48 
49  ! -------------------
50  ! Procedure overloads
51  ! -------------------
52  INTERFACE OPERATOR(==)
53  MODULE PROCEDURE ssu_input_equal
54  END INTERFACE OPERATOR(==)
55 
56 
57  ! -----------------
58  ! Module parameters
59  ! -----------------
60  CHARACTER(*), PARAMETER :: module_version_id = &
61  '$Id: SSU_Input_Define.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
62  ! Release and version
63  INTEGER, PARAMETER :: ssu_input_release = 1 ! This determines structure and file formats.
64  INTEGER, PARAMETER :: ssu_input_version = 1 ! This is just the default data version.
65  ! Close status for write errors
66  CHARACTER(*), PARAMETER :: write_error_status = 'DELETE'
67  ! Literal constants
68  REAL(Double), PARAMETER :: zero = 0.0_double
69  ! Message length
70  INTEGER, PARAMETER :: ml = 256
71  ! SSU instrument specific data
72  INTEGER, PARAMETER :: max_n_channels = 3
73 
74 
75  !--------------------
76  ! Structure defintion
77  !--------------------
78  !:tdoc+:
80  PRIVATE
81  ! Release and version information
82  INTEGER(Long) :: release = ssu_input_release
83  INTEGER(Long) :: version = ssu_input_version
84  ! Time in decimal year (e.g. 2009.08892694 corresponds to 11:00 Feb. 2, 2009)
85  REAL(Double) :: time = zero
86  ! SSU CO2 cell pressures (hPa)
87  REAL(Double) :: cell_pressure(max_n_channels) = zero
88  END TYPE ssu_input_type
89  !:tdoc-:
90 
91 
92 CONTAINS
93 
94 
95 !################################################################################
96 !################################################################################
97 !## ##
98 !## ## PUBLIC MODULE ROUTINES ## ##
99 !## ##
100 !################################################################################
101 !################################################################################
102 
103 !--------------------------------------------------------------------------------
104 !:sdoc+:
105 !
106 ! NAME:
107 ! SSU_Input_IsValid
108 !
109 ! PURPOSE:
110 ! Non-pure function to perform some simple validity checks on a
111 ! SSU_Input object.
112 !
113 ! If invalid data is found, a message is printed to stdout.
114 !
115 ! CALLING SEQUENCE:
116 ! result = SSU_Input_IsValid( ssu )
117 !
118 ! or
119 !
120 ! IF ( SSU_Input_IsValid( ssu ) ) THEN....
121 !
122 ! OBJECTS:
123 ! ssu: SSU_Input object which is to have its
124 ! contents checked.
125 ! UNITS: N/A
126 ! TYPE: SSU_Input_type
127 ! DIMENSION: Scalar
128 ! ATTRIBUTES: INTENT(IN)
129 !
130 ! FUNCTION RESULT:
131 ! result: Logical variable indicating whether or not the input
132 ! passed the check.
133 ! If == .FALSE., object is unused or contains
134 ! invalid data.
135 ! == .TRUE., object can be used.
136 ! UNITS: N/A
137 ! TYPE: LOGICAL
138 ! DIMENSION: Scalar
139 !
140 !:sdoc-:
141 !--------------------------------------------------------------------------------
142 
143  FUNCTION ssu_input_isvalid( ssu ) RESULT( IsValid )
144  TYPE(ssu_input_type), INTENT(IN) :: ssu
145  LOGICAL :: isvalid
146  CHARACTER(*), PARAMETER :: routine_name = 'SSU_Input_IsValid'
147  CHARACTER(ML) :: msg
148 
149  ! Setup
150  isvalid = .true.
151 
152  ! Check time
153  IF ( ssu%Time < zero ) THEN
154  msg = 'Invalid mission time'
155  CALL display_message( routine_name, trim(msg), information )
156  isvalid = .false.
157  END IF
158 
159  ! Check cell pressures
160  IF ( any(ssu%Cell_Pressure < zero) ) THEN
161  msg = 'Invalid cell pressures'
162  CALL display_message( routine_name, trim(msg), information )
163  isvalid = .false.
164  END IF
165 
166  END FUNCTION ssu_input_isvalid
167 
168 
169 !--------------------------------------------------------------------------------
170 !:sdoc+:
171 !
172 ! NAME:
173 ! SSU_Input_Inspect
174 !
175 ! PURPOSE:
176 ! Subroutine to print the contents of an SSU_Input object to stdout.
177 !
178 ! CALLING SEQUENCE:
179 ! CALL SSU_Input_Inspect( ssu )
180 !
181 ! INPUTS:
182 ! ssu: SSU_Input object to display.
183 ! UNITS: N/A
184 ! TYPE: SSU_Input_type
185 ! DIMENSION: Scalar
186 ! ATTRIBUTES: INTENT(IN)
187 !
188 !:sdoc-:
189 !--------------------------------------------------------------------------------
190 
191  SUBROUTINE ssu_input_inspect(ssu)
192  TYPE(ssu_input_type), INTENT(IN) :: ssu
193  WRITE(*,'(3x,"SSU_Input OBJECT")')
194  WRITE(*,'(5x,"Mission time:",1x,es22.15)') ssu%Time
195  WRITE(*,'(5x,"Channel cell pressures:",10(1x,es22.15,:))') ssu%Cell_Pressure
196  END SUBROUTINE ssu_input_inspect
197 
198 
199 !----------------------------------------------------------------------------------
200 !:sdoc+:
201 !
202 ! NAME:
203 ! SSU_Input_ValidRelease
204 !
205 ! PURPOSE:
206 ! Function to check the SSU_Input Release value.
207 !
208 ! CALLING SEQUENCE:
209 ! IsValid = SSU_Input_ValidRelease( SSU_Input )
210 !
211 ! INPUTS:
212 ! SSU_Input: SSU_Input object for which the Release component
213 ! is to be checked.
214 ! UNITS: N/A
215 ! TYPE: SSU_Input_type
216 ! DIMENSION: Scalar
217 ! ATTRIBUTES: INTENT(IN)
218 !
219 ! FUNCTION RESULT:
220 ! IsValid: Logical value defining the release validity.
221 ! UNITS: N/A
222 ! TYPE: LOGICAL
223 ! DIMENSION: Scalar
224 !
225 !:sdoc-:
226 !----------------------------------------------------------------------------------
227 
228  FUNCTION ssu_input_validrelease( self ) RESULT( IsValid )
229  ! Arguments
230  TYPE(ssu_input_type), INTENT(IN) :: self
231  ! Function result
232  LOGICAL :: isvalid
233  ! Local parameters
234  CHARACTER(*), PARAMETER :: routine_name = 'SSU_Input_ValidRelease'
235  ! Local variables
236  CHARACTER(ML) :: msg
237 
238  ! Set up
239  isvalid = .true.
240 
241 
242  ! Check release is not too old
243  IF ( self%Release < ssu_input_release ) THEN
244  isvalid = .false.
245  WRITE( msg,'("An SSU_Input data update is needed. ", &
246  &"SSU_Input release is ",i0,". Valid release is ",i0,"." )' ) &
247  self%Release, ssu_input_release
248  CALL display_message( routine_name, msg, information ); RETURN
249  END IF
250 
251 
252  ! Check release is not too new
253  IF ( self%Release > ssu_input_release ) THEN
254  isvalid = .false.
255  WRITE( msg,'("An SSU_Input software update is needed. ", &
256  &"SSU_Input release is ",i0,". Valid release is ",i0,"." )' ) &
257  self%Release, ssu_input_release
258  CALL display_message( routine_name, msg, information ); RETURN
259  END IF
260 
261  END FUNCTION ssu_input_validrelease
262 
263 
264 !--------------------------------------------------------------------------------
265 !:sdoc+:
266 !
267 ! NAME:
268 ! SSU_Input_DefineVersion
269 !
270 ! PURPOSE:
271 ! Subroutine to return the module version information.
272 !
273 ! CALLING SEQUENCE:
274 ! CALL SSU_Input_DefineVersion( Id )
275 !
276 ! OUTPUTS:
277 ! Id: Character string containing the version Id information
278 ! for the module.
279 ! UNITS: N/A
280 ! TYPE: CHARACTER(*)
281 ! DIMENSION: Scalar
282 ! ATTRIBUTES: INTENT(OUT)
283 !
284 !:sdoc-:
285 !--------------------------------------------------------------------------------
286 
287  SUBROUTINE ssu_input_defineversion( Id )
288  CHARACTER(*), INTENT(OUT) :: id
289  id = module_version_id
290  END SUBROUTINE ssu_input_defineversion
291 
292 
293 !--------------------------------------------------------------------------------
294 !:sdoc+:
295 !
296 ! NAME:
297 ! SSU_Input_SetValue
298 !
299 ! PURPOSE:
300 ! Elemental subroutine to set the values of SSU_Input
301 ! object components.
302 !
303 ! CALLING SEQUENCE:
304 ! CALL SSU_Input_SetValue( SSU_Input , &
305 ! Time = Time , &
306 ! Cell_Pressure = Cell_Pressure, &
307 ! Channel = Channel )
308 !
309 ! OBJECTS:
310 ! SSU_Input: SSU_Input object for which component values
311 ! are to be set.
312 ! UNITS: N/A
313 ! TYPE: SSU_Input_type
314 ! DIMENSION: Scalar or any rank
315 ! ATTRIBUTES: INTENT(IN OUT)
316 !
317 ! OPTIONAL INPUTS:
318 ! Time: SSU instrument mission time.
319 ! UNITS: decimal year
320 ! TYPE: REAL(fp)
321 ! DIMENSION: Scalar or same as SSU_Input
322 ! ATTRIBUTES: INTENT(IN), OPTIONAL
323 !
324 ! Cell_Pressure: SSU channel CO2 cell pressure. Must be
325 ! specified with the Channel optional dummy
326 ! argument.
327 ! UNITS: hPa
328 ! TYPE: REAL(fp)
329 ! DIMENSION: Scalar or same as SSU_Input
330 ! ATTRIBUTES: INTENT(IN), OPTIONAL
331 !
332 ! Channel: SSU channel for which the CO2 cell pressure
333 ! is to be set. Must be specified with the
334 ! Cell_Pressure optional dummy argument.
335 ! UNITS: N/A
336 ! TYPE: INTEGER
337 ! DIMENSION: Scalar or same as SSU_Input
338 ! ATTRIBUTES: INTENT(IN), OPTIONAL
339 !
340 !:sdoc-:
341 !--------------------------------------------------------------------------------
342 
343  ELEMENTAL SUBROUTINE ssu_input_setvalue ( &
344  SSU_Input , &
345  Time , &
346  Cell_Pressure, &
347  Channel )
348  ! Arguments
349  TYPE(ssu_input_type), INTENT(IN OUT) :: ssu_input
350  REAL(fp), OPTIONAL, INTENT(IN) :: time
351  REAL(fp), OPTIONAL, INTENT(IN) :: cell_pressure
352  INTEGER, OPTIONAL, INTENT(IN) :: channel
353  ! Variables
354  INTEGER :: n
355 
356  ! Set values
357  IF ( PRESENT(time) ) ssu_input%Time = time
358  IF ( PRESENT(channel) .AND. PRESENT(cell_pressure) ) THEN
359  n = max(min(channel,max_n_channels),1)
360  ssu_input%Cell_Pressure(n) = cell_pressure
361  END IF
362 
363  END SUBROUTINE ssu_input_setvalue
364 
365 
366 !--------------------------------------------------------------------------------
367 !:sdoc+:
368 !
369 ! NAME:
370 ! SSU_Input_GetValue
371 !
372 ! PURPOSE:
373 ! Elemental subroutine to Get the values of SSU_Input
374 ! object components.
375 !
376 ! CALLING SEQUENCE:
377 ! CALL SSU_Input_GetValue( SSU_Input , &
378 ! Channel = Channel , &
379 ! Time = Time , &
380 ! Cell_Pressure = Cell_Pressure, &
381 ! n_Channels = n_Channels )
382 !
383 ! OBJECTS:
384 ! SSU_Input: SSU_Input object for which component values
385 ! are to be set.
386 ! UNITS: N/A
387 ! TYPE: SSU_Input_type
388 ! DIMENSION: Scalar or any rank
389 ! ATTRIBUTES: INTENT(IN OUT)
390 !
391 ! OPTIONAL INPUTS:
392 ! Channel: SSU channel for which the CO2 cell pressure
393 ! is required.
394 ! UNITS: N/A
395 ! TYPE: INTEGER
396 ! DIMENSION: Scalar or same as SSU_Input
397 ! ATTRIBUTES: INTENT(IN), OPTIONAL
398 !
399 ! OPTIONAL OUTPUTS:
400 ! Time: SSU instrument mission time.
401 ! UNITS: decimal year
402 ! TYPE: REAL(fp)
403 ! DIMENSION: Scalar or same as SSU_Input
404 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
405 !
406 ! Cell_Pressure: SSU channel CO2 cell pressure. Must be
407 ! specified with the Channel optional input
408 ! dummy argument.
409 ! UNITS: hPa
410 ! TYPE: REAL(fp)
411 ! DIMENSION: Scalar or same as SSU_Input
412 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
413 !
414 ! n_Channels: Number of SSU channels..
415 ! UNITS: N/A
416 ! TYPE: INTEGER
417 ! DIMENSION: Scalar or same as SSU_Input
418 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
419 !
420 !:sdoc-:
421 !--------------------------------------------------------------------------------
422 
423  ELEMENTAL SUBROUTINE ssu_input_getvalue( &
424  SSU_Input , &
425  Channel , &
426  Time , &
427  Cell_Pressure, &
428  n_Channels )
429  ! Arguments
430  TYPE(ssu_input_type), INTENT(IN) :: ssu_input
431  INTEGER, OPTIONAL, INTENT(IN) :: channel
432  REAL(fp), OPTIONAL, INTENT(OUT) :: time
433  REAL(fp), OPTIONAL, INTENT(OUT) :: cell_pressure
434  INTEGER, OPTIONAL, INTENT(OUT) :: n_channels
435  ! Variables
436  INTEGER :: n
437 
438  ! Get values
439  IF ( PRESENT(time) ) time = ssu_input%Time
440  IF ( PRESENT(channel) .AND. PRESENT(cell_pressure) ) THEN
441  n = max(min(channel,max_n_channels),1)
442  cell_pressure = ssu_input%Cell_Pressure(n)
443  END IF
444  IF ( PRESENT(n_channels) ) n_channels = max_n_channels
445 
446  END SUBROUTINE ssu_input_getvalue
447 
448 
449 !--------------------------------------------------------------------------------
450 !:sdoc+:
451 !
452 ! NAME:
453 ! SSU_Input_CellPressureIsSet
454 !
455 ! PURPOSE:
456 ! Elemental function to determine if SSU_Input object cell pressures
457 ! are set (i.e. > zero).
458 !
459 ! CALLING SEQUENCE:
460 ! result = SSU_Input_CellPressureIsSet( ssu )
461 !
462 ! or
463 !
464 ! IF ( SSU_Input_CellPressureIsSet( ssu ) ) THEN
465 ! ...
466 ! END IF
467 !
468 ! OBJECTS:
469 ! ssu: SSU_Input object for which the cell pressures
470 ! are to be tested.
471 ! UNITS: N/A
472 ! TYPE: SSU_Input_type
473 ! DIMENSION: Scalar or any rank
474 ! ATTRIBUTES: INTENT(IN)
475 !
476 ! FUNCTION RESULT:
477 ! result: Logical variable indicating whether or not all the
478 ! SSU cell pressures are set.
479 ! If == .FALSE., cell pressure values are <= 0.0hPa and
480 ! thus are considered to be NOT set or valid.
481 ! == .TRUE., cell pressure values are > 0.0hPa and
482 ! thus are considered to be set and valid.
483 ! UNITS: N/A
484 ! TYPE: LOGICAL
485 ! DIMENSION: Scalar
486 !
487 !:sdoc-:
488 !--------------------------------------------------------------------------------
489 
490  ELEMENTAL FUNCTION ssu_input_cellpressureisset( ssu ) RESULT( Is_Set )
491  TYPE(ssu_input_type), INTENT(IN) :: ssu
492  LOGICAL :: is_set
493  is_set = all(ssu%Cell_Pressure > zero)
494  END FUNCTION ssu_input_cellpressureisset
495 
496 
497 !--------------------------------------------------------------------------------
498 !:sdoc+:
499 !
500 ! NAME:
501 ! SSU_Input_ReadFile
502 !
503 ! PURPOSE:
504 ! Function to read SSU_Input object files.
505 !
506 ! CALLING SEQUENCE:
507 ! Error_Status = SSU_Input_ReadFile( &
508 ! SSU_Input , &
509 ! Filename , &
510 ! No_Close = No_Close, &
511 ! Quiet = Quiet )
512 !
513 ! OBJECTS:
514 ! SSU_Input: SSU_Input object containing the data read from file.
515 ! UNITS: N/A
516 ! TYPE: SSU_Input_type
517 ! DIMENSION: Scalar
518 ! ATTRIBUTES: INTENT(OUT)
519 !
520 ! INPUTS:
521 ! Filename: Character string specifying the name of a
522 ! SSU_Input data file to read.
523 ! UNITS: N/A
524 ! TYPE: CHARACTER(*)
525 ! DIMENSION: Scalar
526 ! ATTRIBUTES: INTENT(IN)
527 !
528 ! OPTIONAL INPUTS:
529 ! No_Close: Set this logical argument to *NOT* close the datafile
530 ! upon exiting this routine. This option is required if
531 ! the SSU_Input data is embedded within another file.
532 ! If == .FALSE., File is closed upon function exit [DEFAULT].
533 ! == .TRUE., File is NOT closed upon function exit
534 ! If not specified, default is .FALSE.
535 ! UNITS: N/A
536 ! TYPE: LOGICAL
537 ! DIMENSION: Scalar
538 ! ATTRIBUTES: INTENT(IN), OPTIONAL
539 !
540 ! Quiet: Set this logical argument to suppress INFORMATION
541 ! messages being printed to stdout
542 ! If == .FALSE., INFORMATION messages are OUTPUT [DEFAULT].
543 ! == .TRUE., INFORMATION messages are SUPPRESSED.
544 ! If not specified, default is .FALSE.
545 ! UNITS: N/A
546 ! TYPE: LOGICAL
547 ! DIMENSION: Scalar
548 ! ATTRIBUTES: INTENT(IN), OPTIONAL
549 !
550 ! FUNCTION RESULT:
551 ! Error_Status: The return value is an integer defining the error status.
552 ! The error codes are defined in the Message_Handler module.
553 ! If == SUCCESS, the file read was successful
554 ! == FAILURE, an unrecoverable error occurred.
555 ! UNITS: N/A
556 ! TYPE: INTEGER
557 ! DIMENSION: Scalar
558 !
559 !:sdoc-:
560 !------------------------------------------------------------------------------
561 
562  FUNCTION ssu_input_readfile( &
563  SSU_Input, & ! Output
564  Filename , & ! Input
565  No_Close , & ! Optional input
566  Quiet , & ! Optional input
567  Title , & ! Optional output
568  History , & ! Optional output
569  Comment , & ! Optional output
570  Debug ) & ! Optional input (Debug output control)
571  result( err_stat )
572  ! Arguments
573  TYPE(ssu_input_type), INTENT(OUT) :: ssu_input
574  CHARACTER(*), INTENT(IN) :: filename
575  LOGICAL, OPTIONAL, INTENT(IN) :: no_close
576  LOGICAL, OPTIONAL, INTENT(IN) :: quiet
577  CHARACTER(*), OPTIONAL, INTENT(OUT) :: title
578  CHARACTER(*), OPTIONAL, INTENT(OUT) :: history
579  CHARACTER(*), OPTIONAL, INTENT(OUT) :: comment
580  LOGICAL, OPTIONAL, INTENT(IN) :: debug
581  ! Function result
582  INTEGER :: err_stat
583  ! Function parameters
584  CHARACTER(*), PARAMETER :: routine_name = 'SSU_Input_ReadFile'
585  ! Function variables
586  CHARACTER(ML) :: msg
587  CHARACTER(ML) :: io_msg
588  LOGICAL :: close_file
589  LOGICAL :: noisy
590  INTEGER :: io_stat
591  INTEGER :: fid
592  INTEGER :: n_channels
593  TYPE(ssu_input_type) :: dummy
594 
595  ! Setup
596  err_stat = success
597  ! ...Check No_Close argument
598  close_file = .true.
599  IF ( PRESENT(no_close) ) close_file = .NOT. no_close
600  ! ...Check Quiet argument
601  noisy = .true.
602  IF ( PRESENT(quiet) ) noisy = .NOT. quiet
603  ! ...Override Quiet settings if debug set.
604  IF ( PRESENT(debug) ) THEN
605  IF ( debug ) noisy = .true.
606  END IF
607 
608 
609  ! Check if the file is open.
610  IF ( file_open( filename ) ) THEN
611  ! ...Inquire for the logical unit number
612  INQUIRE( file=filename, number=fid )
613  ! ...Ensure it's valid
614  IF ( fid < 0 ) THEN
615  msg = 'Error inquiring '//trim(filename)//' for its FileID'
616  CALL read_cleanup(); RETURN
617  END IF
618  ELSE
619  ! ...Open the file if it exists
620  IF ( file_exists( filename ) ) THEN
621  err_stat = open_binary_file( filename, fid )
622  IF ( err_stat /= success ) THEN
623  msg = 'Error opening '//trim(filename)
624  CALL read_cleanup(); RETURN
625  END IF
626  ELSE
627  msg = 'File '//trim(filename)//' not found.'
628  CALL read_cleanup(); RETURN
629  END IF
630  END IF
631 
632 
633  ! Read and check the release and version
634  READ( fid, iostat=io_stat, iomsg=io_msg ) &
635  dummy%Release, &
636  dummy%Version
637  IF ( io_stat /= 0 ) THEN
638  msg = 'Error reading Release/Version - '//trim(io_msg)
639  CALL read_cleanup(); RETURN
640  END IF
641  IF ( .NOT. ssu_input_validrelease( dummy ) ) THEN
642  msg = 'SSU_Input Release check failed.'
643  CALL read_cleanup(); RETURN
644  END IF
645 
646 
647  ! Read the dimensions
648  READ( fid, iostat=io_stat, iomsg=io_msg ) &
649  n_channels
650  IF ( io_stat /= 0 ) THEN
651  msg = 'Error reading data dimensions - '//trim(io_msg)
652  CALL read_cleanup(); RETURN
653  END IF
654  ! ...and check 'em
655  IF ( n_channels /= max_n_channels ) THEN
656  msg = 'Invalid channel dimension'
657  CALL read_cleanup(); RETURN
658  END IF
659  ! ...Explicitly assign the version number
660  ssu_input%Version = dummy%Version
661 
662 
663  ! Read the global attributes
664  err_stat = readgatts_binary_file( &
665  fid, &
666  title = title , &
667  history = history, &
668  comment = comment )
669  IF ( err_stat /= success ) THEN
670  msg = 'Error reading global attributes'
671  CALL read_cleanup(); RETURN
672  END IF
673 
674 
675  ! Read the decimal time
676  READ( fid, iostat=io_stat, iomsg=io_msg ) &
677  ssu_input%Time
678  IF ( io_stat /= 0 ) THEN
679  msg = 'Error reading decimal time - '//trim(io_msg)
680  CALL read_cleanup(); RETURN
681  END IF
682 
683 
684  ! Read the cell pressures
685  READ( fid, iostat=io_stat, iomsg=io_msg ) &
686  ssu_input%Cell_Pressure
687  IF ( io_stat /= 0 ) THEN
688  msg = 'Error reading CO2 cell pressures - '//trim(io_msg)
689  CALL read_cleanup(); RETURN
690  END IF
691 
692 
693  ! Close the file
694  IF ( close_file ) THEN
695  CLOSE( fid, iostat=io_stat, iomsg=io_msg )
696  IF ( io_stat /= 0 ) THEN
697  msg = 'Error closing '//trim(filename)//' - '//trim(io_msg)
698  CALL read_cleanup(); RETURN
699  END IF
700  END IF
701 
702  CONTAINS
703 
704  SUBROUTINE read_cleanup()
705  IF ( file_open(filename) ) THEN
706  CLOSE( fid, iostat=io_stat, iomsg=io_msg )
707  IF ( io_stat /= 0 ) &
708  msg = trim(msg)//'; Error closing input file during error cleanup - '//trim(io_msg)
709  END IF
710  err_stat = failure
711  CALL display_message( routine_name, msg, err_stat )
712  END SUBROUTINE read_cleanup
713 
714  END FUNCTION ssu_input_readfile
715 
716 
717 !--------------------------------------------------------------------------------
718 !:sdoc+:
719 !
720 ! NAME:
721 ! SSU_Input_WriteFile
722 !
723 ! PURPOSE:
724 ! Function to write SSU_Input object files.
725 !
726 ! CALLING SEQUENCE:
727 ! Error_Status = SSU_Input_WriteFile( &
728 ! SSU_Input , &
729 ! Filename , &
730 ! No_Close = No_Close, &
731 ! Quiet = Quiet )
732 !
733 ! OBJECTS:
734 ! SSU_Input: SSU_Input object containing the data to write to file.
735 ! UNITS: N/A
736 ! TYPE: SSU_Input_type
737 ! DIMENSION: Scalar
738 ! ATTRIBUTES: INTENT(IN)
739 !
740 ! INPUTS:
741 ! Filename: Character string specifying the name of a
742 ! SSU_Input format data file to write.
743 ! UNITS: N/A
744 ! TYPE: CHARACTER(*)
745 ! DIMENSION: Scalar
746 ! ATTRIBUTES: INTENT(IN)
747 !
748 ! OPTIONAL INPUTS:
749 ! No_Close: Set this logical argument to *NOT* close the datafile
750 ! upon exiting this routine. This option is required if
751 ! the SSU_Input data is to be embedded within another file.
752 ! If == .FALSE., File is closed upon function exit [DEFAULT].
753 ! == .TRUE., File is NOT closed upon function exit
754 ! If not specified, default is .FALSE.
755 ! UNITS: N/A
756 ! TYPE: LOGICAL
757 ! DIMENSION: Scalar
758 ! ATTRIBUTES: INTENT(IN), OPTIONAL
759 !
760 ! Quiet: Set this logical argument to suppress INFORMATION
761 ! messages being printed to stdout
762 ! If == .FALSE., INFORMATION messages are OUTPUT [DEFAULT].
763 ! == .TRUE., INFORMATION messages are SUPPRESSED.
764 ! If not specified, default is .FALSE.
765 ! UNITS: N/A
766 ! TYPE: LOGICAL
767 ! DIMENSION: Scalar
768 ! ATTRIBUTES: INTENT(IN), OPTIONAL
769 !
770 ! FUNCTION RESULT:
771 ! Error_Status: The return value is an integer defining the error status.
772 ! The error codes are defined in the Message_Handler module.
773 ! If == SUCCESS, the file write was successful
774 ! == FAILURE, an unrecoverable error occurred.
775 ! UNITS: N/A
776 ! TYPE: INTEGER
777 ! DIMENSION: Scalar
778 !
779 !:sdoc-:
780 !------------------------------------------------------------------------------
781 
782  FUNCTION ssu_input_writefile( &
783  SSU_Input, & ! Input
784  Filename , & ! Input
785  No_Close , & ! Optional input
786  Quiet , & ! Optional input
787  Title , & ! Optional input
788  History , & ! Optional input
789  Comment , & ! Optional input
790  Debug ) & ! Optional input (Debug output control)
791  result( err_stat )
792  ! Arguments
793  TYPE(ssu_input_type), INTENT(IN) :: ssu_input
794  CHARACTER(*), INTENT(IN) :: filename
795  LOGICAL, OPTIONAL, INTENT(IN) :: no_close
796  LOGICAL, OPTIONAL, INTENT(IN) :: quiet
797  CHARACTER(*), OPTIONAL, INTENT(IN) :: title
798  CHARACTER(*), OPTIONAL, INTENT(IN) :: history
799  CHARACTER(*), OPTIONAL, INTENT(IN) :: comment
800  LOGICAL, OPTIONAL, INTENT(IN) :: debug
801  ! Function result
802  INTEGER :: err_stat
803  ! Function parameters
804  CHARACTER(*), PARAMETER :: routine_name = 'SSU_Input_WriteFile'
805  ! Function variables
806  CHARACTER(ML) :: msg
807  CHARACTER(ML) :: io_msg
808  LOGICAL :: close_file
809  LOGICAL :: noisy
810  INTEGER :: io_stat
811  INTEGER :: fid
812 
813 
814  ! Setup
815  err_stat = success
816  ! ...Check No_Close argument
817  close_file = .true.
818  IF ( PRESENT(no_close) ) close_file = .NOT. no_close
819  ! ...Check Quiet argument
820  noisy = .true.
821  IF ( PRESENT(quiet) ) noisy = .NOT. quiet
822  ! ...Override Quiet settings if debug set.
823  IF ( PRESENT(debug) ) THEN
824  IF ( debug ) noisy = .true.
825  END IF
826 
827 
828  ! Check if the file is open.
829  IF ( file_open( filename ) ) THEN
830  ! ...Inquire for the logical unit number
831  INQUIRE( file=filename, number=fid )
832  ! ...Ensure it's valid
833  IF ( fid < 0 ) THEN
834  msg = 'Error inquiring '//trim(filename)//' for its FileID'
835  CALL write_cleanup(); RETURN
836  END IF
837  ELSE
838  ! ...Open the file for output
839  err_stat = open_binary_file( filename, fid, for_output=.true. )
840  IF ( err_stat /= success ) THEN
841  msg = 'Error opening '//trim(filename)
842  CALL write_cleanup(); RETURN
843  END IF
844  END IF
845 
846 
847  ! Write the release and version
848  WRITE( fid, iostat=io_stat, iomsg=io_msg ) &
849  ssu_input%Release, &
850  ssu_input%Version
851  IF ( io_stat /= 0 ) THEN
852  msg = 'Error writing Release/Version - '//trim(io_msg)
853  CALL write_cleanup(); RETURN
854  END IF
855 
856 
857  ! Write the dimensions
858  WRITE( fid, iostat=io_stat, iomsg=io_msg ) &
860  IF ( io_stat /= 0 ) THEN
861  msg = 'Error writing channel dimension - '//trim(io_msg)
862  CALL write_cleanup(); RETURN
863  END IF
864 
865 
866  ! Write the global attributes
867  err_stat = writegatts_binary_file( &
868  fid, &
869  write_module = module_version_id, &
870  title = title , &
871  history = history, &
872  comment = comment )
873  IF ( err_stat /= success ) THEN
874  msg = 'Error writing global attributes'
875  CALL write_cleanup(); RETURN
876  END IF
877 
878 
879  ! Write the decimal time
880  WRITE( fid, iostat=io_stat, iomsg=io_msg ) &
881  ssu_input%Time
882  IF ( io_stat /= 0 ) THEN
883  msg = 'Error writing decimal time - '//trim(io_msg)
884  CALL write_cleanup(); RETURN
885  END IF
886 
887 
888  ! Write the cell_pressures
889  WRITE( fid, iostat=io_stat, iomsg=io_msg ) &
890  ssu_input%Cell_Pressure
891  IF ( io_stat /= 0 ) THEN
892  msg = 'Error writing cell pressures - '//trim(io_msg)
893  CALL write_cleanup(); RETURN
894  END IF
895 
896 
897  ! Close the file
898  IF ( close_file ) THEN
899  CLOSE( fid, iostat=io_stat, iomsg=io_msg )
900  IF ( io_stat /= 0 ) THEN
901  msg = 'Error closing '//trim(filename)//' - '//trim(io_msg)
902  CALL write_cleanup(); RETURN
903  END IF
904  END IF
905 
906  CONTAINS
907 
908  SUBROUTINE write_cleanup()
909  IF ( file_open(filename) ) THEN
910  CLOSE( fid, iostat=io_stat, iomsg=io_msg )
911  IF ( io_stat /= 0 ) &
912  msg = trim(msg)//'; Error closing output file during error cleanup - '//trim(io_msg)
913  END IF
914  err_stat = failure
915  CALL display_message( routine_name, msg, err_stat )
916  END SUBROUTINE write_cleanup
917 
918  END FUNCTION ssu_input_writefile
919 
920 
921 
922 !################################################################################
923 !################################################################################
924 !## ##
925 !## ## PRIVATE MODULE ROUTINES ## ##
926 !## ##
927 !################################################################################
928 !################################################################################
929 
930  ELEMENTAL FUNCTION ssu_input_equal(x, y) RESULT(is_equal)
931  TYPE(ssu_input_type), INTENT(IN) :: x, y
932  LOGICAL :: is_equal
933  is_equal = (x%Time .equalto. y%Time) .AND. &
934  all(x%Cell_Pressure .equalto. y%Cell_Pressure)
935  END FUNCTION ssu_input_equal
936 
937 END MODULE ssu_input_define
integer function, public ssu_input_readfile(SSU_Input, Filename, No_Close, Quiet, Title, History, Comment, Debug)
integer, parameter, public failure
real(fp), parameter, public zero
integer, parameter, public long
Definition: Type_Kinds.f90:76
elemental logical function ssu_input_equal(x, y)
integer, parameter, public fp
Definition: Type_Kinds.f90:124
integer, parameter ssu_input_release
integer function, public readgatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
elemental subroutine, public ssu_input_getvalue(SSU_Input, Channel, Time, Cell_Pressure, n_Channels)
character(*), parameter module_version_id
logical function, public ssu_input_validrelease(self)
integer, parameter, public double
Definition: Type_Kinds.f90:106
subroutine, public ssu_input_defineversion(Id)
integer function, public ssu_input_writefile(SSU_Input, Filename, No_Close, Quiet, Title, History, Comment, Debug)
integer, save, private max_n_channels
subroutine read_cleanup()
subroutine write_cleanup()
logical function, public ssu_input_isvalid(ssu)
integer function, public open_binary_file(Filename, FileID, For_Output, No_Check)
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
elemental logical function, public ssu_input_cellpressureisset(ssu)
character(*), parameter write_error_status
integer function, public writegatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
#define max(a, b)
Definition: mosaic_util.h:33
integer, parameter ssu_input_version
elemental subroutine, public ssu_input_setvalue(SSU_Input, Time, Cell_Pressure, Channel)
subroutine, public ssu_input_inspect(ssu)
#define min(a, b)
Definition: mosaic_util.h:32
integer, parameter, public success
integer, parameter ml
integer, parameter, public information