FV3 Bundle
ODSSU_Define.f90
Go to the documentation of this file.
1 !
2 ! ODSSU_Define
3 !
4 ! Module defining the ODSSU (Tau coefficient data structure for the SSU sensors).
5 !
6 !
7 ! CREATION HISTORY:
8 ! Written by: Yong Han, NOAA/NESDIS, Oct. 6, 2009
9 !
10 ! Yong Chen, NOAA/NESDIS, 06-Nov-2009
11 ! yong.chen@noaa.gov
12 !
13 
15 
16  ! ------------------
17  ! Environment set up
18  ! ------------------
19  ! Module use
20  USE type_kinds, ONLY: long, double
22  USE odas_define, ONLY: odas_type , &
23  destroy_odas, &
25  USE odps_define, ONLY: odps_type , &
26  destroy_odps, &
29 
30  ! Disable implicit typing
31  IMPLICIT NONE
32 
33 
34  ! ------------
35  ! Visibilities
36  ! ------------
37  ! Everything private by default
38  PRIVATE
39 
40  ! Public types
41  ! ------------
42  PUBLIC :: odssu_type
43  ! The Global unique algorithm ID
44  PUBLIC :: odssu_algorithm
45  ! public routines
46  PUBLIC :: associated_odssu
47  PUBLIC :: destroy_odssu
48  PUBLIC :: allocate_odssu
49  PUBLIC :: checkrelease_odssu
50  PUBLIC :: checkalgorithm_odssu
51  PUBLIC :: info_odssu
52 
53  PUBLIC :: odas_algorithm
54  PUBLIC :: odps_algorithm
55 
56  ! -----------------
57  ! Module parameters
58  ! -----------------
59  ! RCS Id for the module
60  CHARACTER(*), PARAMETER :: module_rcs_id = &
61  '$Id: ODSSU_Define.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
62  ! ODSSU invalid values
63  INTEGER, PARAMETER :: ip_invalid = -1
64  REAL(Double), PARAMETER :: fp_invalid = -1.0_double
65  ! Keyword set value
66  INTEGER, PARAMETER :: set = 1
67  ! String lengths
68  INTEGER, PARAMETER :: sl = 20 ! Sensor Id
69  INTEGER, PARAMETER :: ml = 256 ! Messages
70  ! Current valid release and version numbers
71  INTEGER, PARAMETER :: odssu_release = 6 ! This determines structure and file formats.
72  INTEGER, PARAMETER :: odssu_version = 4 ! This is just the data version.
73  ! The optical depth algorithm name
74  CHARACTER(*), PARAMETER :: odssu_algorithm_name = 'ODSSU'
75  ! ASCII codes for Version routine
76  INTEGER, PARAMETER :: carriage_return = 13
77  INTEGER, PARAMETER :: linefeed = 10
78  ! Invalid sensor ids
79  INTEGER, PARAMETER :: invalid_wmo_satellite_id = 1023
80  INTEGER, PARAMETER :: invalid_wmo_sensor_id = 2047
81  ! The instrument types
82  INTEGER, PARAMETER :: invalid_sensor = 0
83  ! instrument type
84  INTEGER, PARAMETER :: infrared_sensor = 2
85 
86  ! -------------------------
87  ! ODSSU data type definition
88  ! -------------------------
89  TYPE :: odssu_type
90 
91  ! This structure is specific for the Stratospheric Sensor Unit (SSU). To consider
92  ! the variation of cell CO2 pressure, a set of absorption coefficients are derived
93  ! corresponding a set of cell CO2 pressures.
94  ! The simultaneous cell CO2 pressure can be interpolated from the array data
95  ! Ref_Time and Ref_CellPressure.
96  INTEGER :: n_allocates = 0
97  ! Release and version information
98  INTEGER(Long) :: release = odssu_release
99  INTEGER(Long) :: version = odssu_version
100 
101  INTEGER(Long) :: algorithm = odssu_algorithm
102  INTEGER(Long) :: subalgorithm = 0 ! refer to the series algorithm ID 1 for ODAS, 2 for ODPS
103  ! Array dimensions
104  INTEGER(Long) :: n_channels = 0 ! L
105  INTEGER(Long) :: n_absorbers = 0 ! J
106  INTEGER(Long) :: n_tc_cellpressures = 0 ! M
107  INTEGER(Long) :: n_ref_cellpressures = 0 ! N
108  ! Scalar components
109  CHARACTER(SL) :: sensor_id = ' '
110  INTEGER(Long) :: wmo_satellite_id = invalid_wmo_satellite_id
111  INTEGER(Long) :: wmo_sensor_id = invalid_wmo_sensor_id
112  INTEGER(Long) :: sensor_type = infrared_sensor ! fixed for SSUs
113  ! The actual sensor channel numbers
114  INTEGER(Long), POINTER, DIMENSION(:) :: sensor_channel => null() ! L
115  ! The absorber ID and absorber space values
116  INTEGER(Long), POINTER, DIMENSION(:) :: absorber_id => null() ! J
117 
118  ! cell CO2 pressures used in training coefficients, part of TauCoefficients file
119  REAL(Double), POINTER, DIMENSION(:,:) :: tc_cellpressure => null() ! M x L
120  REAL(Double), POINTER, DIMENSION(:) :: ref_time => null() ! N
121  REAL(Double), POINTER, DIMENSION(:,:) :: ref_cellpressure => null() ! N x L
122 
123  ! Tau coefficient series at different cell pressures
124  TYPE(odas_type), POINTER, DIMENSION(:) :: odas => null() ! M
125  TYPE(odps_type), POINTER, DIMENSION(:) :: odps => null() ! M
126 
127  END TYPE odssu_type
128 
129 CONTAINS
130 
131 !--------------------------------------------------------------------------------
132 !
133 ! NAME:
134 ! Associated_ODSSU
135 !
136 ! PURPOSE:
137 ! Function to test the association status of the pointer members of a
138 ! ODSSU structure.
139 !
140 ! CALLING SEQUENCE:
141 ! Association_Status = Associated_ODSSU(ODSSU ,& ! Input
142 ! ANY_Test=Any_Test ) ! Optional input
143 !
144 ! INPUT ARGUMENTS:
145 ! ODSSU: ODSSU structure which is to have its pointer
146 ! member's association status tested.
147 ! UNITS: N/A
148 ! TYPE: ODSSU_type
149 ! DIMENSION: Scalar
150 ! ATTRIBUTES: INTENT(IN)
151 !
152 ! OPTIONAL INPUT ARGUMENTS:
153 ! ANY_Test: Set this argument to test if ANY of the
154 ! ODSSU structure pointer members are associated.
155 ! The default is to test if ALL the pointer members
156 ! are associated.
157 ! If ANY_Test = 0, test if ALL the pointer members
158 ! are associated. (DEFAULT)
159 ! ANY_Test = 1, test if ANY of the pointer members
160 ! are associated.
161 !
162 ! FUNCTION RESULT:
163 ! Association_Status: The return value is a logical value indicating the
164 ! association status of the ODSSU pointer members.
165 ! .TRUE. - if ALL the ODSSU pointer members are
166 ! associated, or if the ANY_Test argument
167 ! is set and ANY of the ODSSU pointer
168 ! members are associated.
169 ! .FALSE. - some or all of the ODSSU pointer
170 ! members are NOT associated.
171 ! UNITS: N/A
172 ! TYPE: LOGICAL
173 ! DIMENSION: Scalar
174 !
175 !--------------------------------------------------------------------------------
176 
177  FUNCTION associated_odssu(ODSSU , & ! Input
178  ANY_Test) & ! Optional input
179  result( association_status )
180  ! Arguments
181  TYPE(odssu_type) , INTENT(IN) :: odssu
182  INTEGER, OPTIONAL, INTENT(IN) :: any_test
183  ! Function result
184  LOGICAL :: association_status
185  ! Local variables
186  LOGICAL :: all_test
187  INTEGER :: i
188 
189  ! Set up
190  ! ------
191  ! Default is to test ALL the pointer members
192  ! for a true association status....
193  all_test = .true.
194  ! ...unless the ANY_Test argument is set.
195  IF ( PRESENT( any_test ) ) THEN
196  IF ( any_test == set ) all_test = .false.
197  END IF
198 
199  ! Test the members that MUST be associated
200  ! ----------------------------------------
201  association_status = .false.
202  IF ( all_test ) THEN
203  IF ( ASSOCIATED( odssu%Sensor_Channel ) .AND. &
204  ASSOCIATED( odssu%Absorber_ID ) .AND. &
205  ASSOCIATED( odssu%TC_CellPressure ) .AND. &
206  ASSOCIATED( odssu%Ref_Time ) .AND. &
207  ASSOCIATED( odssu%Ref_CellPressure ) ) THEN
208  association_status = .true.
209  ENDIF
210  IF(odssu%subAlgorithm == odas_algorithm) THEN
211  association_status = association_status .AND. ASSOCIATED( odssu%ODAS )
212  DO i = 1, odssu%n_TC_CellPressures
213  association_status = association_status .AND. associated_odas( odssu%ODAS(i) )
214  END DO
215  ENDIF
216 
217  IF(odssu%subAlgorithm == odps_algorithm) THEN
218  association_status = association_status .AND. ASSOCIATED( odssu%ODPS )
219  DO i = 1, odssu%n_TC_CellPressures
220  association_status = association_status .AND. associated_odps( odssu%ODPS(i) )
221  END DO
222  ENDIF
223  ELSE
224  IF ( ASSOCIATED( odssu%Sensor_Channel ) .OR. &
225  ASSOCIATED( odssu%Absorber_ID ) .OR. &
226  ASSOCIATED( odssu%TC_CellPressure ) .OR. &
227  ASSOCIATED( odssu%Ref_Time ) .OR. &
228  ASSOCIATED( odssu%Ref_CellPressure ) ) THEN
229  association_status = .true.
230  END IF
231  IF(odssu%subAlgorithm == odas_algorithm) THEN
232  association_status = association_status .OR. ASSOCIATED( odssu%ODAS )
233  DO i = 1, odssu%n_TC_CellPressures
234  association_status = association_status .OR. associated_odas( odssu%ODAS(i) )
235  END DO
236  ENDIF
237 
238  IF(odssu%subAlgorithm == odps_algorithm) THEN
239  association_status = association_status .OR. ASSOCIATED( odssu%ODPS )
240  DO i = 1, odssu%n_TC_CellPressures
241  association_status = association_status .OR. associated_odps( odssu%ODPS(i) )
242  END DO
243  ENDIF
244  END IF
245 
246  END FUNCTION associated_odssu
247 
248 !------------------------------------------------------------------------------
249 !
250 ! NAME:
251 ! Destroy_ODSSU
252 !
253 ! PURPOSE:
254 ! Function to re-initialize the scalar and pointer members of ODSSU
255 ! data structures.
256 !
257 ! CALLING SEQUENCE:
258 ! Error_Status = Destroy_ODSSU(ODSSU , & ! Output
259 ! RCS_Id =RCS_Id , & ! Revision control
260 ! Message_Log=Message_Log ) ! Error messaging
261 !
262 ! OUTPUT ARGUMENTS:
263 ! ODSSU: Re-initialized ODSSU structure.
264 ! UNITS: N/A
265 ! TYPE: ODSSU_type
266 ! DIMENSION: Scalar
267 ! ATTRIBUTES: INTENT(IN OUT)
268 !
269 ! OPTIONAL INPUT ARGUMENTS:
270 ! Message_Log: Character string specifying a filename in which any
271 ! messages will be logged. If not specified, or if an
272 ! error occurs opening the log file, the default action
273 ! is to output messages to standard output.
274 ! UNITS: N/A
275 ! TYPE: CHARACTER(*)
276 ! DIMENSION: Scalar
277 ! ATTRIBUTES: OPTIONAL, INTENT(IN)
278 !
279 ! OPTIONAL OUTPUT ARGUMENTS:
280 ! RCS_Id: Character string containing the Revision Control
281 ! System Id field for the module.
282 ! UNITS: N/A
283 ! TYPE: CHARACTER(*)
284 ! DIMENSION: Scalar
285 ! ATTRIBUTES: OPTIONAL, INTENT(OUT)
286 !
287 ! FUNCTION RESULT:
288 ! Error_Status: The return value is an integer defining the error status.
289 ! The error codes are defined in the Message_Handler module.
290 ! If == SUCCESS the structure re-initialisation was successful
291 ! == FAILURE - an error occurred, or
292 ! - the structure internal allocation counter
293 ! is not equal to zero (0) upon exiting this
294 ! function. This value is incremented and
295 ! decremented for every structure allocation
296 ! and deallocation respectively.
297 ! UNITS: N/A
298 ! TYPE: INTEGER
299 ! DIMENSION: Scalar
300 !
301 ! COMMENTS:
302 ! Note the INTENT on the output ODSSU argument is IN OUT rather than
303 ! just OUT. This is necessary because the argument may be defined upon
304 ! input. To prevent memory leaks, the IN OUT INTENT is a must.
305 !
306 !------------------------------------------------------------------------------
307 
308  FUNCTION destroy_odssu(ODSSU , & ! Output
309  No_Clear , & ! Optional input
310  RCS_Id , & ! Revision control
311  Message_Log) & ! Error messaging
312  result( error_status )
313  ! Arguments
314  TYPE(odssu_type) , INTENT(IN OUT) :: odssu
315  INTEGER, OPTIONAL, INTENT(IN) :: no_clear
316  CHARACTER(*), OPTIONAL, INTENT(OUT) :: rcs_id
317  CHARACTER(*), OPTIONAL, INTENT(IN) :: message_log
318  ! Function result
319  INTEGER :: error_status
320  ! Local parameters
321  CHARACTER(*), PARAMETER :: routine_name = 'Destroy_ODSSU'
322  ! Local variables
323  CHARACTER(ML) :: message
324  LOGICAL :: clear
325  INTEGER :: allocate_status1, allocate_status2
326  INTEGER :: i
327 
328  ! Set up
329  ! ------
330  error_status = success
331  IF ( PRESENT( rcs_id ) ) rcs_id = module_rcs_id
332  ! Default is to clear scalar members...
333  clear = .true.
334  ! ....unless the No_Clear argument is set
335  IF ( PRESENT( no_clear ) ) THEN
336  IF ( no_clear == set ) clear = .false.
337  END IF
338 
339  ! If ALL components are NOT associated, do nothing
340  IF ( .NOT. associated_odssu( odssu ) ) RETURN
341 
342  ! Destroy ODx
343  IF(odssu%subAlgorithm == odas_algorithm) THEN
344  DO i = 1, odssu%n_TC_CellPressures
345  error_status = destroy_odas( odssu%ODAS(i), &
346  message_log = message_log)
347  IF( error_status /= success )THEN
348  CALL display_message( routine_name, &
349  "Error deallocating ODAS for ODSSU", &
350  error_status, &
351  message_log=message_log )
352  RETURN
353  END IF
354  END DO
355  ENDIF
356  IF(odssu%subAlgorithm == odps_algorithm) THEN
357  DO i = 1, odssu%n_TC_CellPressures
358  error_status = destroy_odps( odssu%ODPS(i), &
359  message_log = message_log)
360  IF( error_status /= success )THEN
361  CALL display_message( routine_name, &
362  "Error deallocating ODPS for ODSSU", &
363  error_status, &
364  message_log=message_log )
365  RETURN
366  END IF
367  END DO
368  ENDIF
369 
370  ! Deallocate the regular arrays components
371  ! ----------------------------------------
372  DEALLOCATE( odssu%Sensor_Channel , &
373  odssu%Absorber_ID , &
374  odssu%TC_CellPressure , &
375  odssu%Ref_Time , &
376  odssu%Ref_CellPressure, &
377  stat=allocate_status1 )
378 
379  IF(odssu%subAlgorithm == odas_algorithm) THEN
380  DEALLOCATE(odssu%ODAS, stat=allocate_status2)
381  ENDIF
382  IF(odssu%subAlgorithm == odps_algorithm) THEN
383  DEALLOCATE(odssu%ODPS, stat=allocate_status2)
384  ENDIF
385 
386  IF ( allocate_status1 /= 0 ) THEN
387  error_status = failure
388  WRITE( message,'("Error deallocating ODSSU components 1. STAT = ",i0)' ) &
389  allocate_status1
390  CALL display_message( routine_name, &
391  trim(message), &
392  error_status, &
393  message_log=message_log )
394  END IF
395  IF ( allocate_status2 /= 0 ) THEN
396  error_status = failure
397  WRITE( message,'("Error deallocating ODSSU components 2. STAT = ",i0)' ) &
398  allocate_status2
399  CALL display_message( routine_name, &
400  trim(message), &
401  error_status, &
402  message_log=message_log )
403  END IF
404 
405  ! Clear the scalar members
406  IF ( clear ) CALL clear_odssu( odssu )
407 
408  ! Reinitialise the dimensions
409  odssu%n_Channels = 0
410  odssu%n_TC_CellPressures = 0
411  odssu%n_Ref_CellPressures = 0
412 
413 
414  ! Decrement and test allocation counter
415  ! -------------------------------------
416  odssu%n_Allocates = odssu%n_Allocates - 1
417  IF ( odssu%n_Allocates /= 0 ) THEN
418  error_status = failure
419  WRITE( message,'("Allocation counter /= 0, Value = ",i0)' ) &
420  odssu%n_Allocates
421  CALL display_message( routine_name, &
422  trim(message), &
423  error_status, &
424  message_log=message_log )
425  END IF
426  END FUNCTION destroy_odssu
427 
428 !------------------------------------------------------------------------------
429 !
430 ! NAME:
431 ! Allocate_ODSSU
432 !
433 ! PURPOSE:
434 ! Function to allocate the pointer members of the ODSSU
435 ! data structure.
436 !
437 ! CALLING SEQUENCE:
438 ! Error_Status = Allocate_ODSSU(n_Absorbers , & ! Input
439 ! n_Channels , & ! Input
440 ! n_TC_CellPressures , & ! Input
441 ! n_Ref_CellPressures , & ! Input
442 ! ODSSU , & ! Output
443 ! RCS_Id =RCS_Id , & ! Revision control
444 ! Message_Log=Message_Log ) ! Error messaging
445 !
446 ! INPUT ARGUMENTS:
447 !
448 ! n_Absorbers: Number of absorbers dimension.
449 ! Must be > 0.
450 ! UNITS: N/A
451 ! TYPE: INTEGER
452 ! DIMENSION: Scalar
453 ! ATTRIBUTES: INTENT(IN)
454 !
455 ! n_Channels: Number of channels dimension.
456 ! Must be > 0.
457 ! UNITS: N/A
458 ! TYPE: INTEGER
459 ! DIMENSION: Scalar
460 ! ATTRIBUTES: INTENT(IN)
461 !
462 ! n_TC_CellPressures: Number of TC cell pressure dimension.
463 ! Must be > 0.
464 ! UNITS: N/A
465 ! TYPE: INTEGER
466 ! DIMENSION: Scalar
467 ! ATTRIBUTES: INTENT(IN)
468 !
469 ! n_Ref_CellPressures: Number of refference cell pressure dimension.
470 ! Must be > 0.
471 ! UNITS: N/A
472 ! TYPE: INTEGER
473 ! DIMENSION: Scalar
474 ! ATTRIBUTES: INTENT(IN)
475 !
476 ! OUTPUT ARGUMENTS:
477 ! ODSSU: ODSSU structure with allocated
478 ! pointer members
479 ! UNITS: N/A
480 ! TYPE: ODSSU_type
481 ! DIMENSION: Scalar
482 ! ATTRIBUTES: INTENT(OUT)
483 !
484 ! OPTIONAL INPUT ARGUMENTS:
485 ! Message_Log: Character string specifying a filename in
486 ! which any messages will be logged. If not
487 ! specified, or if an error occurs opening
488 ! the log file, the default action is to
489 ! output messages to standard output.
490 ! UNITS: N/A
491 ! TYPE: CHARACTER(*)
492 ! DIMENSION: Scalar
493 ! ATTRIBUTES: OPTIONAL, INTENT(IN)
494 !
495 ! OPTIONAL OUTPUT ARGUMENTS:
496 ! RCS_Id: Character string containing the Revision Control
497 ! System Id field for the module.
498 ! UNITS: N/A
499 ! TYPE: CHARACTER(*)
500 ! DIMENSION: Scalar
501 ! ATTRIBUTES: OPTIONAL, INTENT(OUT)
502 !
503 ! FUNCTION RESULT:
504 ! Error_Status: The return value is an integer defining the error status.
505 ! The error codes are defined in the Message_Handler module.
506 ! If == SUCCESS the structure re-initialisation was successful
507 ! == FAILURE - an error occurred, or
508 ! - the structure internal allocation counter
509 ! is not equal to one (1) upon exiting this
510 ! function. This value is incremented and
511 ! decremented for every structure allocation
512 ! and deallocation respectively.
513 ! UNITS: N/A
514 ! TYPE: INTEGER
515 ! DIMENSION: Scalar
516 !
517 ! COMMENTS:
518 ! The pointer members of the ODSSU structure in the ODSSU structure will not be
519 ! allocated in this routine.
520 !
521 ! Note the INTENT on the output ODSSU argument is IN OUT rather than
522 ! just OUT. This is necessary because the argument may be defined upon
523 ! input. To prevent memory leaks, the IN OUT INTENT is a must.
524 !
525 !------------------------------------------------------------------------------
526 
527  FUNCTION allocate_odssu(n_Absorbers , & ! Input
528  n_Channels , & ! Input
529  n_TC_CellPressures , & ! Input
530  n_Ref_CellPressures, & ! Input
531  ODSSU , & ! Output
532  RCS_Id , & ! Revision control
533  Message_Log ) & ! Error messaging
534  result( error_status )
535  ! Arguments
536  INTEGER , INTENT(IN) :: n_absorbers
537  INTEGER , INTENT(IN) :: n_channels
538  INTEGER , INTENT(IN) :: n_tc_cellpressures
539  INTEGER , INTENT(IN) :: n_ref_cellpressures
540  TYPE(odssu_type) , INTENT(IN OUT) :: odssu
541  CHARACTER(*), OPTIONAL, INTENT(OUT) :: rcs_id
542  CHARACTER(*), OPTIONAL, INTENT(IN) :: message_log
543  ! Function result
544  INTEGER :: error_status
545  ! Local parameters
546  CHARACTER(*), PARAMETER :: routine_name = 'Allocate_ODSSU'
547  ! Local variables
548  CHARACTER(ML) :: message
549  INTEGER :: allocate_status1, allocate_status2
550 
551  ! Set up
552  ! ------
553  error_status = success
554  IF ( PRESENT( rcs_id ) ) rcs_id = module_rcs_id
555 
556  ! Check dimension input
557  IF ( n_absorbers < 1 .OR. &
558  n_channels < 1 .OR. &
559  n_tc_cellpressures < 1 .OR. &
560  n_ref_cellpressures < 1 ) THEN
561  error_status = failure
562  CALL display_message( routine_name, &
563  'Input ODSSU dimensions must all be > 0.', &
564  error_status, &
565  message_log=message_log )
566  RETURN
567  END IF
568 
569  ! Check if ANY pointers are already associated.
570  ! If they are, deallocate them but leave scalars.
571  IF ( associated_odssu( odssu, any_test=set ) ) THEN
572  error_status = destroy_odssu(odssu, &
573  no_clear=set, &
574  message_log=message_log )
575  IF ( error_status /= success ) THEN
576  CALL display_message( routine_name, &
577  'Error deallocating ODSSU prior to reallocation.', &
578  error_status, &
579  message_log=message_log )
580  RETURN
581  END IF
582  END IF
583 
584  ! Allocate the data arrays
585  ! ------------------------
586  ALLOCATE( odssu%TC_CellPressure( n_tc_cellpressures, n_channels) , &
587  odssu%Ref_Time( n_ref_cellpressures ) , &
588  odssu%Ref_CellPressure( n_ref_cellpressures, n_channels), &
589  odssu%Sensor_Channel( n_channels ) , &
590  odssu%Absorber_ID( n_absorbers ) , &
591  stat = allocate_status1 )
592  IF(odssu%subAlgorithm == odas_algorithm) THEN
593  ALLOCATE(odssu%ODAS( n_tc_cellpressures ), stat=allocate_status2)
594  ENDIF
595  IF(odssu%subAlgorithm == odps_algorithm) THEN
596  ALLOCATE(odssu%ODPS( n_tc_cellpressures ), stat=allocate_status2)
597  ENDIF
598 
599  IF ( allocate_status1 /= 0 .OR. allocate_status2 /= 0) THEN
600  error_status = failure
601  WRITE( message,'("Error allocating ODSSU data arrays. STAT = ",i0)' ) &
602  allocate_status1
603  CALL display_message( routine_name, &
604  trim(message), &
605  error_status, &
606  message_log=message_log )
607  RETURN
608  END IF
609 
610  ! Assign the dimensions and initialise arrays
611  odssu%n_Absorbers = n_absorbers
612  odssu%n_Channels = n_channels
613  odssu%n_TC_CellPressures = n_tc_cellpressures
614  odssu%n_Ref_CellPressures = n_ref_cellpressures
615 
616  odssu%Sensor_Channel = 0
617  odssu%Absorber_ID = ip_invalid
618  odssu%TC_CellPressure = fp_invalid
619  odssu%Ref_Time = fp_invalid
620  odssu%Ref_CellPressure = fp_invalid
621 
622 
623  ! Increment and test allocation counter
624  ! -------------------------------------
625  odssu%n_Allocates = odssu%n_Allocates + 1
626  IF ( odssu%n_Allocates /= 1 ) THEN
627  error_status = failure
628  WRITE( message,'("Allocation counter /= 1, Value = ",i0)' ) &
629  odssu%n_Allocates
630  CALL display_message( routine_name, &
631  trim(message), &
632  error_status, &
633  message_log=message_log )
634  RETURN
635  END IF
636 
637  END FUNCTION allocate_odssu
638 
639 
640 !----------------------------------------------------------------------------------
641 !
642 ! NAME:
643 ! CheckRelease_ODSSU
644 !
645 ! PURPOSE:
646 ! Function to check the ODSSU Release value.
647 !
648 ! CALLING SEQUENCE:
649 ! Error_Status = CheckRelease_ODSSU( ODSSU , & ! Input
650 ! RCS_Id = RCS_Id , & ! Revision control
651 ! Message_Log=Message_Log ) ! Error messaging
652 !
653 ! INPUT ARGUMENTS:
654 ! ODSSU: ODSSU structure for which the Release member
655 ! is to be checked.
656 ! UNITS: N/A
657 ! TYPE: ODSSU_type
658 ! DIMENSION: Scalar
659 ! ATTRIBUTES: INTENT(OUT)
660 !
661 ! OPTIONAL INPUT ARGUMENTS:
662 ! Message_Log: Character string specifying a filename in which any
663 ! messages will be logged. If not specified, or if an
664 ! error occurs opening the log file, the default action
665 ! is to output messages to standard output.
666 ! UNITS: N/A
667 ! TYPE: CHARACTER(*)
668 ! DIMENSION: Scalar
669 ! ATTRIBUTES: OPTIONAL, INTENT(IN)
670 ! OPTIONAL OUTPUT ARGUMENTS:
671 ! RCS_Id: Character string containing the Revision Control
672 ! System Id field for the module.
673 ! UNITS: N/A
674 ! TYPE: CHARACTER(*)
675 ! DIMENSION: Scalar
676 ! ATTRIBUTES: OPTIONAL, INTENT(OUT)
677 !
678 ! FUNCTION RESULT:
679 ! Error_Status: The return value is an integer defining the error status.
680 ! The error codes are defined in the Message_Handler module.
681 ! If == SUCCESS the structure Release value is valid.
682 ! == FAILURE the structure Release value is NOT valid
683 ! and either a data file file or software
684 ! update is required.
685 ! UNITS: N/A
686 ! TYPE: INTEGER
687 ! DIMENSION: Scalar
688 !
689 !----------------------------------------------------------------------------------
690 
691  FUNCTION checkrelease_odssu(ODSSU , & ! Input
692  RCS_Id , & ! Revision control
693  Message_Log) & ! Error messaging
694  result( error_status )
695  ! Arguments
696  TYPE(odssu_type) , INTENT(IN) :: odssu
697  CHARACTER(*), OPTIONAL, INTENT(OUT) :: rcs_id
698  CHARACTER(*), OPTIONAL, INTENT(IN) :: message_log
699  ! Function result
700  INTEGER :: error_status
701  ! Local parameters
702  CHARACTER(*), PARAMETER :: routine_name = 'CheckRelease_ODSSU'
703  ! Local variables
704  CHARACTER(ML) :: message
705 
706  ! Set up
707  ! ------
708  error_status = success
709  IF ( PRESENT( rcs_id ) ) rcs_id = module_rcs_id
710 
711 
712  ! Check the release
713  ! -----------------
714  ! Check that release is not too old
715  IF ( odssu%Release < odssu_release ) THEN
716  error_status = failure
717  WRITE( message, '( "An ODSSU data update is needed. ", &
718  &"ODSSU release is ", i2, &
719  &". Valid release is ",i2,"." )' ) &
720  odssu%Release, odssu_release
721  CALL display_message( routine_name, &
722  trim(message), &
723  error_status, &
724  message_log=message_log )
725  RETURN
726  END IF
727 
728  ! Check that release is not too new
729  IF ( odssu%Release > odssu_release ) THEN
730  error_status = failure
731  WRITE( message, '( "An ODSSU software update is needed. ", &
732  &"ODSSU release is ", i2, &
733  &". Valid release is ",i2,"." )' ) &
734  odssu%Release, odssu_release
735  CALL display_message( routine_name, &
736  trim(message), &
737  error_status, &
738  message_log=message_log )
739  RETURN
740  END IF
741 
742  END FUNCTION checkrelease_odssu
743 
744 
745 !----------------------------------------------------------------------------------
746 !
747 ! NAME:
748 ! CheckAlgorithm_ODSSU
749 !
750 ! PURPOSE:
751 ! Function to check the ODSSU Algorithm value.
752 !
753 ! CALLING SEQUENCE:
754 ! Error_Status = CheckAlgorithm_ODSSU(ODSSU , & ! Input
755 ! RCS_Id = RCS_Id , & ! Revision control
756 ! Message_Log=Message_Log ) ! Error messaging
757 !
758 ! INPUT ARGUMENTS:
759 ! ODSSU: ODSSU structure for which the Algorithm member
760 ! is to be checked.
761 ! UNITS: N/A
762 ! TYPE: ODSSU_type
763 ! DIMENSION: Scalar
764 ! ATTRIBUTES: INTENT(OUT)
765 !
766 ! OPTIONAL INPUT ARGUMENTS:
767 ! Message_Log: Character string specifying a filename in which any
768 ! messages will be logged. If not specified, or if an
769 ! error occurs opening the log file, the default action
770 ! is to output messages to standard output.
771 ! UNITS: N/A
772 ! TYPE: CHARACTER(*)
773 ! DIMENSION: Scalar
774 ! ATTRIBUTES: OPTIONAL, INTENT(IN)
775 ! OPTIONAL OUTPUT ARGUMENTS:
776 ! RCS_Id: Character string containing the Revision Control
777 ! System Id field for the module.
778 ! UNITS: N/A
779 ! TYPE: CHARACTER(*)
780 ! DIMENSION: Scalar
781 ! ATTRIBUTES: OPTIONAL, INTENT(OUT)
782 !
783 ! FUNCTION RESULT:
784 ! Error_Status: The return value is an integer defining the error status.
785 ! The error codes are defined in the Message_Handler module.
786 ! If == SUCCESS the structure Algorithm value is valid.
787 ! == FAILURE the structure Algorithm value is NOT valid.
788 ! UNITS: N/A
789 ! TYPE: INTEGER
790 ! DIMENSION: Scalar
791 !
792 !----------------------------------------------------------------------------------
793 
794  FUNCTION checkalgorithm_odssu(ODSSU , & ! Input
795  RCS_Id , & ! Revision control
796  Message_Log) & ! Error messaging
797  result( error_status )
798  ! Arguments
799  TYPE(odssu_type) , INTENT(IN) :: odssu
800  CHARACTER(*), OPTIONAL, INTENT(OUT) :: rcs_id
801  CHARACTER(*), OPTIONAL, INTENT(IN) :: message_log
802  ! Function result
803  INTEGER :: error_status
804  ! Local parameters
805  CHARACTER(*), PARAMETER :: routine_name = 'CheckAlgorithm_ODSSU'
806 
807  ! Set up
808  ! ------
809  error_status = success
810  IF ( PRESENT(rcs_id) ) rcs_id = module_rcs_id
811 
812 
813  ! Check the algorithm ID
814  ! ----------------------
815  IF ( odssu%Algorithm /= odssu_algorithm ) THEN
816  error_status = failure
817  CALL display_message( routine_name, &
818  'The ODSSU Algorithm ID check failed. '//&
819  'The data structure is not an ODSSU structure', &
820  error_status, &
821  message_log=message_log )
822  RETURN
823  END IF
824 
825  END FUNCTION checkalgorithm_odssu
826 
827 !------------------------------------------------------------------------------
828 !
829 ! NAME:
830 ! Info_ODSSU
831 !
832 ! PURPOSE:
833 ! Subroutine to return a string containing version and dimension
834 ! information about the ODSSU data structure.
835 !
836 ! CALLING SEQUENCE:
837 ! CALL Info_ODSSU(ODSSU , & ! Input
838 ! Info , & ! Output
839 ! RCS_Id=RCS_Id ) ! Revision control
840 !
841 ! INPUT ARGUMENTS:
842 ! ODSSU: Filled ODSSU structure.
843 ! UNITS: N/A
844 ! TYPE: ODSSU_type
845 ! DIMENSION: Scalar
846 ! ATTRIBUTES: INTENT(IN)
847 !
848 ! OUTPUT ARGUMENTS:
849 ! Info: String containing version and dimension information
850 ! about the passed ODSSU data structure.
851 ! UNITS: N/A
852 ! TYPE: CHARACTER(*)
853 ! DIMENSION: Scalar
854 ! ATTRIBUTES: INTENT(OUT)
855 !
856 ! OPTIONAL OUTPUT ARGUMENTS:
857 ! RCS_Id: Character string containing the Revision Control
858 ! System Id field for the module.
859 ! UNITS: N/A
860 ! TYPE: CHARACTER(*)
861 ! DIMENSION: Scalar
862 ! ATTRIBUTES: OPTIONAL, INTENT(OUT)
863 !
864 !------------------------------------------------------------------------------
865 
866  SUBROUTINE info_odssu( ODSSU , & ! Input
867  Info , & ! Output
868  RCS_Id ) ! Revision control
869  ! Arguments
870  TYPE(odssu_type) , INTENT(IN) :: odssu
871  CHARACTER(*), INTENT(OUT) :: info
872  CHARACTER(*), OPTIONAL, INTENT(OUT) :: rcs_id
873  ! Local variables
874  CHARACTER(2000) :: longstring
875 
876  ! Set up
877  ! ------
878  IF ( PRESENT( rcs_id ) ) rcs_id = module_rcs_id
879 
880  ! Write the required data to the local string
881  ! -------------------------------------------
882  WRITE( longstring,'( a,3x,"ODSSU RELEASE.VERSION: ",i2,".",i2.2,2x,&
883  &"SUBALGORITHM=",i2,2x,&
884  &"N_ABSORBERS=",i2,2x,&
885  &"N_CHANNELS=",i0,2x, &
886  &"N_TC_CELLPRESSURES=",i2,2x, &
887  &"N_REF_CELLPRESSURES=",i0)' ) &
888  achar(carriage_return)//achar(linefeed), &
889  odssu%Release, odssu%Version, &
890  odssu%subAlgorithm, &
891  odssu%n_Absorbers, &
892  odssu%n_Channels, &
893  odssu%n_TC_CellPressures, &
894  odssu%n_Ref_CellPressures
895 
896  ! Trim the output based on the
897  ! dummy argument string length
898  ! ----------------------------
899  info = longstring(1:min( len(info), len_trim(longstring) ))
900 
901  END SUBROUTINE info_odssu
902 
903 
904 
905 !##################################################################################
906 !##################################################################################
907 !## ##
908 !## ## PRIVATE MODULE ROUTINES ## ##
909 !## ##
910 !##################################################################################
911 !##################################################################################
912 
913 !----------------------------------------------------------------------------------
914 !
915 ! NAME:
916 ! Clear_ODSSU
917 !
918 ! PURPOSE:
919 ! Subroutine to clear the scalar members of a ODSSU structure.
920 !
921 ! CALLING SEQUENCE:
922 ! CALL Clear_ODSSU( ODSSU ) ! Output
923 !
924 ! OUTPUT ARGUMENTS:
925 ! ODSSU: ODSSU structure for which the scalar members have
926 ! been cleared.
927 ! UNITS: N/A
928 ! TYPE: ODSSU_type
929 ! DIMENSION: Scalar
930 ! ATTRIBUTES: INTENT(IN OUT)
931 !
932 !
933 !----------------------------------------------------------------------------------
934 
935  SUBROUTINE clear_odssu( ODSSU )
936  TYPE(ODSSU_type), INTENT(IN OUT) :: ODSSU
937  odssu%Release = odssu_release
938  odssu%Version = odssu_version
939  odssu%Algorithm = odssu_algorithm
940  odssu%subAlgorithm = 0
941  odssu%Sensor_Id = ' '
942  odssu%Sensor_Type = invalid_sensor
943  odssu%WMO_Satellite_ID = invalid_wmo_satellite_id
944  odssu%WMO_Sensor_ID = invalid_wmo_sensor_id
945  END SUBROUTINE clear_odssu
946 
947 END MODULE odssu_define
integer, parameter, public failure
integer, parameter carriage_return
integer, parameter linefeed
integer, parameter, public warning
real(double), parameter fp_invalid
integer, parameter, public long
Definition: Type_Kinds.f90:76
integer function, public destroy_odps(ODPS, No_Clear, RCS_Id, Message_Log)
integer function, public checkalgorithm_odssu(ODSSU, RCS_Id, Message_Log)
integer, parameter, public double
Definition: Type_Kinds.f90:106
integer, parameter invalid_wmo_satellite_id
integer, parameter odssu_version
subroutine clear_odssu(ODSSU)
character(*), parameter module_rcs_id
integer, parameter ml
integer, parameter infrared_sensor
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
integer, parameter invalid_sensor
integer function, public destroy_odssu(ODSSU, No_Clear, RCS_Id, Message_Log)
integer function, public destroy_odas(ODAS, No_Clear, RCS_Id, Message_Log)
logical function, public associated_odps(ODPS, ANY_Test)
subroutine, public info_odssu(ODSSU, Info, RCS_Id)
integer, parameter, public odssu_algorithm
integer, parameter, public odps_algorithm
integer function, public allocate_odssu(n_Absorbers, n_Channels, n_TC_CellPressures, n_Ref_CellPressures, ODSSU, RCS_Id, Message_Log)
logical function, public associated_odas(ODAS, ANY_Test)
integer, parameter odssu_release
integer, parameter, public odas_algorithm
integer, parameter ip_invalid
integer function, public checkrelease_odssu(ODSSU, RCS_Id, Message_Log)
integer, parameter set
character(*), parameter odssu_algorithm_name
integer, parameter invalid_wmo_sensor_id
#define min(a, b)
Definition: mosaic_util.h:32
integer, parameter sl
integer, parameter, public success
logical function, public associated_odssu(ODSSU, ANY_Test)