FV3 Bundle
SpcCoeff_Binary_IO.f90
Go to the documentation of this file.
1 !
2 ! SpcCoeff_Binary_IO
3 !
4 ! Module containing routines to read and write Binary format
5 ! SpcCoeff data files.
6 !
7 !
8 ! CREATION HISTORY:
9 ! Written by: Paul van Delst, 18-Mar-2002
10 ! paul.vandelst@noaa.gov
11 !
12 
14 
15  ! ------------------
16  ! Environment set up
17  ! ------------------
18  ! Module use
19  USE type_kinds , ONLY: long, double
23  USE spccoeff_define , ONLY: spccoeff_type , &
26  spccoeff_create , &
37  ! Disable implicit typing
38  IMPLICIT NONE
39 
40 
41  ! ------------
42  ! Visibilities
43  ! ------------
44  PRIVATE
46  PUBLIC :: spccoeff_binary_readfile
49 
50 
51  ! -----------------
52  ! Module parameters
53  ! -----------------
54  CHARACTER(*), PARAMETER :: module_version_id = &
55  '$Id: SpcCoeff_Binary_IO.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
56  ! Default message length
57  INTEGER, PARAMETER :: ml = 512
58  ! Ancillary data indicator
59  INTEGER, PARAMETER :: data_missing = 0
60  INTEGER, PARAMETER :: data_present = 1
61 
62 
63 CONTAINS
64 
65 
66 !################################################################################
67 !################################################################################
68 !## ##
69 !## ## PUBLIC MODULE ROUTINES ## ##
70 !## ##
71 !################################################################################
72 !################################################################################
73 
74 !------------------------------------------------------------------------------
75 !:sdoc+:
76 !
77 ! NAME:
78 ! SpcCoeff_Binary_InquireFile
79 !
80 ! PURPOSE:
81 ! Function to inquire a Binary format SpcCoeff file.
82 !
83 ! CALLING SEQUENCE:
84 ! Error_Status = SpcCoeff_Binary_InquireFile( &
85 ! Filename , &
86 ! n_Channels = n_Channels , &
87 ! Release = Release , &
88 ! Version = Version , &
89 ! Sensor_Id = Sensor_Id , &
90 ! WMO_Satellite_Id = WMO_Satellite_Id, &
91 ! WMO_Sensor_Id = WMO_Sensor_Id )
92 !
93 ! INPUTS:
94 ! Filename: Character string specifying the name of the binary
95 ! SpcCoeff data file to inquire.
96 ! UNITS: N/A
97 ! TYPE: CHARACTER(*)
98 ! DIMENSION: Scalar
99 ! ATTRIBUTES: INTENT(IN)
100 !
101 ! OPTIONAL OUTPUTS:
102 ! n_Channels: Number of sensor channels.
103 ! UNITS: N/A
104 ! TYPE: INTEGER
105 ! DIMENSION: Scalar
106 ! ATTRIBUTES: INTENT(IN)
107 !
108 ! Release: The data/file release number. Used to check
109 ! for data/software mismatch.
110 ! UNITS: N/A
111 ! TYPE: INTEGER
112 ! DIMENSION: Scalar
113 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
114 !
115 ! Version: The data/file version number. Used for
116 ! purposes only in identifying the dataset for
117 ! a particular release.
118 ! UNITS: N/A
119 ! TYPE: INTEGER
120 ! DIMENSION: Scalar
121 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
122 !
123 ! Sensor_Id: Character string sensor/platform identifier.
124 ! UNITS: N/A
125 ! TYPE: CHARACTER(*)
126 ! DIMENSION: Scalar
127 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
128 !
129 ! WMO_Satellite_Id: The WMO code used to identify satellite platforms.
130 ! UNITS: N/A
131 ! TYPE: INTEGER
132 ! DIMENSION: Scalar
133 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
134 !
135 ! WMO_Sensor_Id: The WMO code used to identify sensors.
136 ! UNITS: N/A
137 ! TYPE: INTEGER
138 ! DIMENSION: Scalar
139 ! ATTRIBUTES: INTENT(OUT), OPTIONAL
140 !
141 ! FUNCTION RESULT:
142 ! Error_Status: The return value is an integer defining the error
143 ! status. The error codes are defined in the
144 ! Message_Handler module.
145 ! If == SUCCESS the file inquire was successful
146 ! == FAILURE an unrecoverable error occurred.
147 ! UNITS: N/A
148 ! TYPE: INTEGER
149 ! DIMENSION: Scalar
150 !
151 !:sdoc-:
152 !------------------------------------------------------------------------------
153 
154  FUNCTION spccoeff_binary_inquirefile( &
155  Filename , & ! Input
156  n_Channels , & ! Optional output
157  Release , & ! Optional Output
158  Version , & ! Optional Output
159  Sensor_Id , & ! Optional Output
160  WMO_Satellite_Id, & ! Optional Output
161  WMO_Sensor_Id ) & ! Optional Output
162  result( err_stat )
163  ! Arguments
164  CHARACTER(*), INTENT(IN) :: filename
165  INTEGER , OPTIONAL, INTENT(OUT) :: n_channels
166  INTEGER , OPTIONAL, INTENT(OUT) :: release
167  INTEGER , OPTIONAL, INTENT(OUT) :: version
168  CHARACTER(*), OPTIONAL, INTENT(OUT) :: sensor_id
169  INTEGER , OPTIONAL, INTENT(OUT) :: wmo_satellite_id
170  INTEGER , OPTIONAL, INTENT(OUT) :: wmo_sensor_id
171  ! Function result
172  INTEGER :: err_stat
173  ! Function parameters
174  CHARACTER(*), PARAMETER :: routine_name = 'SpcCoeff_InquireFile(Binary)'
175  ! Function variables
176  CHARACTER(ML) :: msg
177  INTEGER :: io_stat
178  INTEGER :: fid
179  TYPE(spccoeff_type) :: spccoeff
180 
181 
182  ! Setup
183  err_stat = success
184  ! ...Check that the file exists
185  IF ( .NOT. file_exists( filename ) ) THEN
186  msg = 'File '//trim(filename)//' not found.'
187  CALL inquire_cleanup(); RETURN
188  END IF
189 
190 
191  ! Open the file
192  err_stat = open_binary_file( filename, fid )
193  IF ( err_stat /= success ) THEN
194  msg = 'Error opening '//trim(filename)
195  CALL inquire_cleanup(); RETURN
196  END IF
197 
198 
199  ! Read the release and version
200  READ( fid,iostat=io_stat ) spccoeff%Release, spccoeff%Version
201  IF ( io_stat /= 0 ) THEN
202  WRITE( msg,'("Error reading Release/Version. IOSTAT = ",i0)' ) io_stat
203  CALL inquire_cleanup(); RETURN
204  END IF
205 
206 
207  ! Read the dimensions
208  READ( fid, iostat=io_stat ) &
209  spccoeff%n_Channels
210  IF ( io_stat /= 0 ) THEN
211  WRITE( msg,'("Error reading dimension values from ",a,". IOSTAT = ",i0)' ) &
212  trim(filename), io_stat
213  CALL inquire_cleanup(); RETURN
214  END IF
215 
216 
217  ! Read the sensor ids
218  READ( fid, iostat=io_stat ) &
219  spccoeff%Sensor_Id , &
220  spccoeff%Sensor_Type , &
221  spccoeff%WMO_Satellite_Id, &
222  spccoeff%WMO_Sensor_Id
223  IF ( io_stat /= 0 ) THEN
224  WRITE( msg, '("Error reading sensor information from ",a,". IOSTAT = ",i0)' ) &
225  trim(filename), io_stat
226  CALL inquire_cleanup(); RETURN
227  END IF
228 
229 
230  ! Close the file
231  CLOSE( fid, iostat=io_stat )
232  IF ( io_stat /= 0 ) THEN
233  WRITE( msg,'("Error closing ",a,". IOSTAT = ",i0)' ) trim(filename), io_stat
234  CALL inquire_cleanup(); RETURN
235  END IF
236 
237 
238  ! Assign the return arguments
239  IF ( PRESENT(n_channels ) ) n_channels = spccoeff%n_Channels
240  IF ( PRESENT(release ) ) release = spccoeff%Release
241  IF ( PRESENT(version ) ) version = spccoeff%Version
242  IF ( PRESENT(sensor_id ) ) sensor_id = spccoeff%Sensor_Id
243  IF ( PRESENT(wmo_satellite_id) ) wmo_satellite_id = spccoeff%WMO_Satellite_Id
244  IF ( PRESENT(wmo_sensor_id ) ) wmo_sensor_id = spccoeff%WMO_Sensor_Id
245 
246  CONTAINS
247 
248  SUBROUTINE inquire_cleanup()
249  ! Close file if necessary
250  IF ( file_open(fid) ) THEN
251  CLOSE( fid,iostat=io_stat )
252  IF ( io_stat /= 0 ) &
253  msg = trim(msg)//'; Error closing input file during error cleanup'
254  END IF
255  ! Set error status and print error message
256  err_stat = failure
257  CALL display_message( routine_name, msg, err_stat )
258  END SUBROUTINE inquire_cleanup
259 
260  END FUNCTION spccoeff_binary_inquirefile
261 
262 
263 !--------------------------------------------------------------------------------
264 !:sdoc+:
265 !
266 ! NAME:
267 ! SpcCoeff_Binary_ReadFile
268 !
269 ! PURPOSE:
270 ! Function to read SpcCoeff object files in Binary format.
271 !
272 ! CALLING SEQUENCE:
273 ! Error_Status = SpcCoeff_Binary_ReadFile( &
274 ! Filename , &
275 ! SpcCoeff , &
276 ! Quiet = Quiet )
277 !
278 ! INPUTS:
279 ! Filename: Character string specifying the name of a
280 ! SpcCoeff format data file to read.
281 ! UNITS: N/A
282 ! TYPE: CHARACTER(*)
283 ! DIMENSION: Scalar
284 ! ATTRIBUTES: INTENT(IN)
285 !
286 ! OUTPUTS:
287 ! SpcCoeff: SpcCoeff object containing the spectral
288 ! coefficient data.
289 ! UNITS: N/A
290 ! TYPE: SpcCoeff_type
291 ! DIMENSION: Scalar
292 ! ATTRIBUTES: INTENT(OUT)
293 !
294 ! OPTIONAL INPUTS:
295 ! Quiet: Set this logical argument to suppress INFORMATION
296 ! messages being printed to stdout
297 ! If == .FALSE., INFORMATION messages are OUTPUT [DEFAULT].
298 ! == .TRUE., INFORMATION messages are SUPPRESSED.
299 ! If not specified, default is .FALSE.
300 ! UNITS: N/A
301 ! TYPE: LOGICAL
302 ! DIMENSION: Scalar
303 ! ATTRIBUTES: INTENT(IN), OPTIONAL
304 !
305 ! FUNCTION RESULT:
306 ! Error_Status: The return value is an integer defining the error status.
307 ! The error codes are defined in the Message_Handler module.
308 ! If == SUCCESS, the file read was successful
309 ! == FAILURE, an unrecoverable error occurred.
310 ! UNITS: N/A
311 ! TYPE: INTEGER
312 ! DIMENSION: Scalar
313 !
314 !:sdoc-:
315 !------------------------------------------------------------------------------
316 
317  FUNCTION spccoeff_binary_readfile( &
318  Filename, & ! Input
319  SpcCoeff, & ! Output
320  Quiet , & ! Optional input
321  Debug ) & ! Optional input (Debug output control)
322  result( err_stat )
323  ! Arguments
324  CHARACTER(*), INTENT(IN) :: filename
325  TYPE(spccoeff_type), INTENT(OUT) :: spccoeff
326  LOGICAL, OPTIONAL, INTENT(IN) :: quiet
327  LOGICAL, OPTIONAL, INTENT(IN) :: debug
328  ! Function result
329  INTEGER :: err_stat
330  ! Function parameters
331  CHARACTER(*), PARAMETER :: routine_name = 'SpcCoeff_ReadFile(Binary)'
332  ! Function variables
333  CHARACTER(ML) :: msg, io_msg
334  LOGICAL :: noisy
335  INTEGER :: io_stat
336  INTEGER :: fid
337  INTEGER(Long) :: ac_present
338  INTEGER(Long) :: nc_present
339  TYPE(spccoeff_type) :: dummy
340 
341 
342  ! Setup
343  err_stat = success
344  ! ...Check Quiet argument
345  noisy = .true.
346  IF ( PRESENT(quiet) ) noisy = .NOT. quiet
347  ! ...Override Quiet settings if debug set.
348  IF ( PRESENT(debug) ) THEN
349  IF ( debug ) noisy = .true.
350  END IF
351 
352 
353  ! Open the file
354  IF ( file_exists( filename ) ) THEN
355  err_stat = open_binary_file( filename, fid )
356  IF ( err_stat /= success ) THEN
357  msg = 'Error opening '//trim(filename)
358  CALL read_cleanup(); RETURN
359  END IF
360  ELSE
361  msg = 'File '//trim(filename)//' not found.'
362  CALL read_cleanup(); RETURN
363  END IF
364 
365 
366  ! Read and check the release and version
367  READ( fid, iostat=io_stat ) &
368  dummy%Release, &
369  dummy%Version
370  IF ( io_stat /= 0 ) THEN
371  WRITE( msg,'("Error reading Release/Version. IOSTAT = ",i0)' ) io_stat
372  CALL read_cleanup(); RETURN
373  END IF
374  IF ( .NOT. spccoeff_validrelease( dummy ) ) THEN
375  msg = 'SpcCoeff Release check failed.'
376  CALL read_cleanup(); RETURN
377  END IF
378 
379 
380  ! Read the spectral coefficient data
381  ! ...Read the dimensions
382  READ( fid, iostat=io_stat ) dummy%n_Channels
383  IF ( io_stat /= 0 ) THEN
384  WRITE( msg,'("Error reading data dimensions. IOSTAT = ",i0)' ) io_stat
385  CALL read_cleanup(); RETURN
386  END IF
387  ! ...Allocate the object
388  CALL spccoeff_create( spccoeff , &
389  dummy%n_Channels )
390  IF ( .NOT. spccoeff_associated( spccoeff ) ) THEN
391  msg = 'SpcCoeff object allocation failed.'
392  CALL read_cleanup(); RETURN
393  END IF
394  ! ...Read the sensor info
395  READ( fid, iostat=io_stat ) &
396  spccoeff%Sensor_Id , &
397  spccoeff%Sensor_Type , &
398  spccoeff%WMO_Satellite_Id, &
399  spccoeff%WMO_Sensor_Id
400  IF ( io_stat /= 0 ) THEN
401  WRITE( msg,'("Error reading sensor ids. IOSTAT = ",i0)' ) io_stat
402  CALL read_cleanup(); RETURN
403  END IF
404  ! ...Read the channel data
405  READ( fid, iostat=io_stat, iomsg=io_msg ) &
406  spccoeff%Sensor_Channel , &
407  spccoeff%Polarization , &
408  spccoeff%Channel_Flag , &
409  spccoeff%Frequency , &
410  spccoeff%Wavenumber , &
411  spccoeff%Planck_C1 , &
412  spccoeff%Planck_C2 , &
413  spccoeff%Band_C1 , &
414  spccoeff%Band_C2 , &
415  spccoeff%Cosmic_Background_Radiance, &
416  spccoeff%Solar_Irradiance
417  IF ( io_stat /= 0 ) THEN
418  msg = 'Error reading channel data. '//trim(io_msg)
419  CALL read_cleanup(); RETURN
420  END IF
421 
422 
423  ! Explicitly assign the version number
424  spccoeff%Version = dummy%Version
425 
426 
427  ! Read the antenna correction data if it's present
428  ! ...Read the data indicator
429  READ( fid, iostat=io_stat ) ac_present
430  IF ( io_stat /= 0 ) THEN
431  WRITE( msg,'("Error reading antenna correction data indicator. IOSTAT = ",i0)' ) io_stat
432  CALL read_cleanup(); RETURN
433  END IF
434  ! ...Read the antenna correction data
435  IF ( ac_present == data_present ) THEN
436  err_stat = accoeff_binary_readfile( &
437  filename , &
438  spccoeff%AC , &
439  no_close = .true., &
440  quiet = quiet , &
441  debug = debug )
442  IF ( err_stat /= success ) THEN
443  msg = 'Error reading antenna correction data.'
444  CALL read_cleanup(); RETURN
445  END IF
446  ! ..Check that the ACCoeff data is for the same sensor
447  IF ( spccoeff%Sensor_Id /= spccoeff%AC%Sensor_Id .OR. &
448  spccoeff%WMO_Satellite_Id /= spccoeff%AC%WMO_Satellite_Id .OR. &
449  spccoeff%WMO_Sensor_Id /= spccoeff%AC%WMO_Sensor_Id .OR. &
450  any( spccoeff%Sensor_Channel /= spccoeff%AC%Sensor_Channel ) ) THEN
451  msg = 'Antenna correction sensor information is inconsistent with SpcCoeff'
452  CALL read_cleanup(); RETURN
453  END IF
454  END IF
455 
456 
457  ! Read the NLTE correction data if it's present
458  ! ...Read the data indicator
459  READ( fid, iostat=io_stat ) nc_present
460  IF ( io_stat /= 0 ) THEN
461  WRITE( msg,'("Error reading NLTE correction data indicator. IOSTAT = ",i0)' ) io_stat
462  CALL read_cleanup(); RETURN
463  END IF
464  ! ...Read the NLTE correction data
465  IF ( nc_present == data_present ) THEN
466  err_stat = nltecoeff_binary_readfile( &
467  filename , &
468  spccoeff%NC , &
469  no_close = .true., &
470  quiet = quiet , &
471  debug = debug )
472  IF ( err_stat /= success ) THEN
473  msg = 'Error reading NLTE correction data.'
474  CALL read_cleanup(); RETURN
475  END IF
476  ! ..Check that the NLTECoeff data is for the same sensor
477  IF ( spccoeff%Sensor_Id /= spccoeff%NC%Sensor_Id .OR. &
478  spccoeff%WMO_Satellite_Id /= spccoeff%NC%WMO_Satellite_Id .OR. &
479  spccoeff%WMO_Sensor_Id /= spccoeff%NC%WMO_Sensor_Id .OR. &
480  any( spccoeff%Sensor_Channel /= spccoeff%NC%Sensor_Channel ) ) THEN
481  msg = 'non-LTE correction sensor information is inconsistent with SpcCoeff'
482  CALL read_cleanup(); RETURN
483  END IF
484  END IF
485 
486 
487  ! Close the file
488  CLOSE( fid,iostat=io_stat )
489  IF ( io_stat /= 0 ) THEN
490  WRITE( msg,'("Error closing ",a,". IOSTAT = ",i0)' ) trim(filename), io_stat
491  CALL read_cleanup(); RETURN
492  END IF
493 
494 
495  ! Output an info message
496  IF ( noisy ) THEN
497  CALL spccoeff_info( spccoeff, msg, nocomponents = .true. )
498  CALL display_message( routine_name, 'FILE: '//trim(filename)//'; '//trim(msg), information )
499  END IF
500 
501  CONTAINS
502 
503  SUBROUTINE read_cleanup()
504  IF ( file_open(filename) ) THEN
505  CLOSE( fid,iostat=io_stat )
506  IF ( io_stat /= 0 ) &
507  msg = trim(msg)//'; Error closing input file during error cleanup.'
508  END IF
509  CALL spccoeff_destroy( spccoeff )
510  err_stat = failure
511  CALL display_message( routine_name, msg, err_stat )
512  END SUBROUTINE read_cleanup
513 
514  END FUNCTION spccoeff_binary_readfile
515 
516 
517 !--------------------------------------------------------------------------------
518 !:sdoc+:
519 !
520 ! NAME:
521 ! SpcCoeff_Binary_WriteFile
522 !
523 ! PURPOSE:
524 ! Function to write SpcCoeff object files in Binary format.
525 !
526 ! CALLING SEQUENCE:
527 ! Error_Status = SpcCoeff_Binary_WriteFile( &
528 ! Filename , &
529 ! SpcCoeff , &
530 ! Quiet = Quiet )
531 !
532 ! INPUTS:
533 ! Filename: Character string specifying the name of a
534 ! SpcCoeff format data file to write.
535 ! UNITS: N/A
536 ! TYPE: CHARACTER(*)
537 ! DIMENSION: Scalar
538 ! ATTRIBUTES: INTENT(IN)
539 !
540 ! SpcCoeff: SpcCoeff object containing the spectral
541 ! coefficient data.
542 ! UNITS: N/A
543 ! TYPE: SpcCoeff_type
544 ! DIMENSION: Scalar
545 ! ATTRIBUTES: INTENT(IN)
546 !
547 ! OPTIONAL INPUTS:
548 ! Quiet: Set this logical argument to suppress INFORMATION
549 ! messages being printed to stdout
550 ! If == .FALSE., INFORMATION messages are OUTPUT [DEFAULT].
551 ! == .TRUE., INFORMATION messages are SUPPRESSED.
552 ! If not specified, default is .FALSE.
553 ! UNITS: N/A
554 ! TYPE: LOGICAL
555 ! DIMENSION: Scalar
556 ! ATTRIBUTES: INTENT(IN), OPTIONAL
557 !
558 ! FUNCTION RESULT:
559 ! Error_Status: The return value is an integer defining the error status.
560 ! The error codes are defined in the Message_Handler module.
561 ! If == SUCCESS, the file write was successful
562 ! == FAILURE, an unrecoverable error occurred.
563 ! UNITS: N/A
564 ! TYPE: INTEGER
565 ! DIMENSION: Scalar
566 !
567 !:sdoc-:
568 !------------------------------------------------------------------------------
569 
570  FUNCTION spccoeff_binary_writefile( &
571  Filename, & ! Input
572  SpcCoeff, & ! Output
573  Quiet , & ! Optional input
574  Debug ) & ! Optional input (Debug output control)
575  result( err_stat )
576  ! Arguments
577  CHARACTER(*), INTENT(IN) :: filename
578  TYPE(spccoeff_type), INTENT(IN) :: spccoeff
579  LOGICAL, OPTIONAL, INTENT(IN) :: quiet
580  LOGICAL, OPTIONAL, INTENT(IN) :: debug
581  ! Function result
582  INTEGER :: err_stat
583  ! Function parameters
584  CHARACTER(*), PARAMETER :: routine_name = 'SpcCoeff_WriteFile(Binary)'
585  CHARACTER(*), PARAMETER :: write_error_status = 'DELETE'
586  ! Function variables
587  CHARACTER(ML) :: msg
588  LOGICAL :: noisy
589  INTEGER :: io_stat
590  INTEGER :: fid
591  INTEGER :: ac_present
592  INTEGER :: nc_present
593 
594 
595  ! Setup
596  err_stat = success
597  ! ...Check Quiet argument
598  noisy = .true.
599  IF ( PRESENT(quiet) ) noisy = .NOT. quiet
600  ! ...Override Quiet settings if debug set.
601  IF ( PRESENT(debug) ) THEN
602  IF ( debug ) noisy = .true.
603  END IF
604  ! ...Check there is data to write
605  IF ( .NOT. spccoeff_associated( spccoeff ) ) THEN
606  msg = 'SpcCoeff object is empty.'
607  CALL write_cleanup(); RETURN
608  END IF
609 
610 
611  ! Open the file
612  err_stat = open_binary_file( filename, fid, for_output=.true. )
613  IF ( err_stat /= success ) THEN
614  msg = 'Error opening '//trim(filename)
615  CALL write_cleanup(); RETURN
616  END IF
617 
618 
619  ! Write the release and version
620  WRITE( fid,iostat=io_stat ) &
621  spccoeff%Release, &
622  spccoeff%Version
623  IF ( io_stat /= 0 ) THEN
624  WRITE( msg,'("Error writing Release/Version. IOSTAT = ",i0)' ) io_stat
625  CALL write_cleanup(); RETURN
626  END IF
627 
628 
629  ! Write the spectral coefficient data
630  ! ...Write the dimensions
631  WRITE( fid, iostat=io_stat ) spccoeff%n_Channels
632  IF ( io_stat /= 0 ) THEN
633  WRITE( msg,'("Error writing data dimensions. IOSTAT = ",i0)' ) io_stat
634  CALL write_cleanup(); RETURN
635  END IF
636  ! ...Write the sensor info
637  WRITE( fid, iostat=io_stat ) &
638  spccoeff%Sensor_Id , &
639  spccoeff%Sensor_Type , &
640  spccoeff%WMO_Satellite_Id, &
641  spccoeff%WMO_Sensor_Id
642  IF ( io_stat /= 0 ) THEN
643  WRITE( msg,'("Error writing sensor ids. IOSTAT = ",i0)' ) io_stat
644  CALL write_cleanup(); RETURN
645  END IF
646  ! ...Write the channel data
647  WRITE( fid, iostat=io_stat ) &
648  spccoeff%Sensor_Channel , &
649  spccoeff%Polarization , &
650  spccoeff%Channel_Flag , &
651  spccoeff%Frequency , &
652  spccoeff%Wavenumber , &
653  spccoeff%Planck_C1 , &
654  spccoeff%Planck_C2 , &
655  spccoeff%Band_C1 , &
656  spccoeff%Band_C2 , &
657  spccoeff%Cosmic_Background_Radiance, &
658  spccoeff%Solar_Irradiance
659  IF ( io_stat /= 0 ) THEN
660  WRITE( msg,'("Error writing channel data. IOSTAT = ",i0)' ) io_stat
661  CALL write_cleanup(); RETURN
662  END IF
663 
664 
665  ! Write the antenna correction data if it's present
666  IF ( accoeff_associated( spccoeff%AC ) ) THEN
667  ac_present = data_present
668  ELSE
669  ac_present = data_missing
670  END IF
671  ! ...Write the data indicator
672  WRITE( fid, iostat=io_stat ) ac_present
673  IF ( io_stat /= 0 ) THEN
674  WRITE( msg,'("Error writing antenna correction data indicator. IOSTAT = ",i0)' ) io_stat
675  CALL write_cleanup(); RETURN
676  END IF
677  ! ...Write the antenna correction data
678  IF ( ac_present == data_present ) THEN
679  err_stat = accoeff_binary_writefile( &
680  filename , &
681  spccoeff%AC , &
682  no_close = .true., &
683  quiet = quiet , &
684  debug = debug )
685  IF ( err_stat /= success ) THEN
686  msg = 'Error writing antenna correction data.'
687  CALL write_cleanup(); RETURN
688  END IF
689  ! ..Check that the ACCoeff data is for the same sensor
690  IF ( spccoeff%Sensor_Id /= spccoeff%AC%Sensor_Id .OR. &
691  spccoeff%WMO_Satellite_Id /= spccoeff%AC%WMO_Satellite_Id .OR. &
692  spccoeff%WMO_Sensor_Id /= spccoeff%AC%WMO_Sensor_Id .OR. &
693  any( spccoeff%Sensor_Channel /= spccoeff%AC%Sensor_Channel ) ) THEN
694  msg = 'Antenna correction sensor information is inconsistent with SpcCoeff'
695  CALL write_cleanup(); RETURN
696  END IF
697  END IF
698 
699 
700  ! Write the NLTE correction data if it's present
701  IF ( nltecoeff_associated( spccoeff%NC ) ) THEN
702  nc_present = data_present
703  ELSE
704  nc_present = data_missing
705  END IF
706  ! ...Write the data indicator
707  WRITE( fid, iostat=io_stat ) nc_present
708  IF ( io_stat /= 0 ) THEN
709  WRITE( msg,'("Error writing NLTE correction data indicator. IOSTAT = ",i0)' ) io_stat
710  CALL write_cleanup(); RETURN
711  END IF
712  ! ...Write the NLTE correction data
713  IF ( nc_present == data_present ) THEN
714  err_stat = nltecoeff_binary_writefile( &
715  filename , &
716  spccoeff%NC , &
717  no_close = .true., &
718  quiet = quiet , &
719  debug = debug )
720  IF ( err_stat /= success ) THEN
721  msg = 'Error writing NLTE correction data.'
722  CALL write_cleanup(); RETURN
723  END IF
724  ! ..Check that the NLTECoeff data is for the same sensor
725  IF ( spccoeff%Sensor_Id /= spccoeff%NC%Sensor_Id .OR. &
726  spccoeff%WMO_Satellite_Id /= spccoeff%NC%WMO_Satellite_Id .OR. &
727  spccoeff%WMO_Sensor_Id /= spccoeff%NC%WMO_Sensor_Id .OR. &
728  any( spccoeff%Sensor_Channel /= spccoeff%NC%Sensor_Channel ) ) THEN
729  msg = 'non-LTE correction sensor information is inconsistent with SpcCoeff'
730  CALL write_cleanup(); RETURN
731  END IF
732  END IF
733 
734 
735  ! Close the file
736  CLOSE( fid,status='KEEP',iostat=io_stat )
737  IF ( io_stat /= 0 ) THEN
738  WRITE( msg,'("Error closing ",a,". IOSTAT = ",i0)' ) trim(filename), io_stat
739  CALL write_cleanup(); RETURN
740  END IF
741 
742 
743  ! Output an info message
744  IF ( noisy ) THEN
745  CALL spccoeff_info( spccoeff, msg, nocomponents = .true. )
746  CALL display_message( routine_name, 'FILE: '//trim(filename)//'; '//trim(msg), information )
747  END IF
748 
749  CONTAINS
750 
751  SUBROUTINE write_cleanup()
752  IF ( file_open(filename) ) THEN
753  CLOSE( fid, status=write_error_status, iostat=io_stat )
754  IF ( io_stat /= 0 ) &
755  msg = trim(msg)//'; Error closing input file during error cleanup.'
756  END IF
757  err_stat = failure
758  CALL display_message( routine_name, msg, err_stat )
759  END SUBROUTINE write_cleanup
760 
761  END FUNCTION spccoeff_binary_writefile
762 
763 
764 !--------------------------------------------------------------------------------
765 !:sdoc+:
766 !
767 ! NAME:
768 ! SpcCoeff_Binary_IOVersion
769 !
770 ! PURPOSE:
771 ! Subroutine to return the version information for the
772 ! I/O module(s).
773 !
774 ! CALLING SEQUENCE:
775 ! CALL SpcCoeff_IOVersion( Id )
776 !
777 ! OUTPUTS:
778 ! Id: Character string containing the version Id information for the
779 ! structure I/O module(s). If the string length is sufficient,
780 ! the version information for all the modules (this, and those
781 ! for the derived type components) are concatenated. Otherwise
782 ! only the version id for this module is returned.
783 ! UNITS: N/A
784 ! TYPE: CHARACTER(*)
785 ! DIMENSION: Scalar
786 ! ATTRIBUTES: INTENT(OUT)
787 !
788 !:sdoc-:
789 !--------------------------------------------------------------------------------
790 
791  SUBROUTINE spccoeff_binary_ioversion( Id )
792  CHARACTER(*), INTENT(OUT) :: id
793  INTEGER, PARAMETER :: carriage_return = 13
794  INTEGER, PARAMETER :: linefeed = 10
795  INTEGER, PARAMETER :: sl = 256
796  CHARACTER(SL) :: ac_id
797  CHARACTER(SL) :: nc_id
798  CHARACTER(SL*3) :: io_id
799  CALL accoeff_binary_ioversion( ac_id )
800  CALL nltecoeff_binary_ioversion( nc_id )
801  io_id = module_version_id//';'//achar(carriage_return)//achar(linefeed)//&
802  ' '//trim(ac_id)//';'//achar(carriage_return)//achar(linefeed)//&
803  ' '//trim(nc_id)
804  IF ( len_trim(io_id) <= len(id) ) THEN
805  id = io_id
806  ELSE
807  id = module_version_id
808  END IF
809  END SUBROUTINE spccoeff_binary_ioversion
810 
811 END MODULE spccoeff_binary_io
integer, parameter data_present
integer, parameter, public failure
integer function, public accoeff_binary_readfile(Filename, ACCoeff, No_Close, Quiet, Debug)
integer function, public accoeff_binary_writefile(Filename, ACCoeff, No_Close, Quiet, Debug)
integer, parameter, public long
Definition: Type_Kinds.f90:76
elemental subroutine, public spccoeff_destroy(SpcCoeff)
integer function, public spccoeff_binary_readfile(Filename, SpcCoeff, Quiet, Debug)
integer, parameter, public double
Definition: Type_Kinds.f90:106
integer function, public nltecoeff_binary_readfile(Filename, NLTECoeff, No_Close, Quiet, Debug)
integer function, public spccoeff_binary_writefile(Filename, SpcCoeff, Quiet, Debug)
subroutine inquire_cleanup()
integer function, public nltecoeff_binary_writefile(Filename, NLTECoeff, No_Close, Quiet, Debug)
integer function, public spccoeff_binary_inquirefile(Filename, n_Channels, Release, Version, Sensor_Id, WMO_Satellite_Id, WMO_Sensor_Id)
subroutine, public spccoeff_info(SpcCoeff, Info, NoComponents)
elemental subroutine, public spccoeff_create(SpcCoeff, n_Channels)
subroutine read_cleanup()
integer, parameter data_missing
subroutine write_cleanup()
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 ml
subroutine, public nltecoeff_binary_ioversion(Id)
subroutine, public accoeff_binary_ioversion(Id)
logical function, public spccoeff_validrelease(SpcCoeff)
integer, parameter, public success
subroutine, public spccoeff_binary_ioversion(Id)
character(*), parameter module_version_id
elemental logical function, public accoeff_associated(ACCoeff)
elemental logical function, public spccoeff_associated(SpcCoeff)
integer, parameter, public information
elemental logical function, public nltecoeff_associated(NLTECoeff)