FV3 Bundle
TauCoeff_Define.f90
Go to the documentation of this file.
1 !
2 ! TauCoeff_Define
3 !
4 ! Module defining the TauCoeff data structure and containing routines to
5 ! manipulate it.
6 !
7 !
8 ! CREATION HISTORY:
9 ! Written by: Paul van Delst, 18-Mar-2002
10 ! paul.vandelst@noaa.gov
11 !
12 ! Updated by: David Groff, EMC/SAIC Oct-2009
13 ! david.groff@noaa.gov
14 !
15 
17 
18  ! ------------------
19  ! Environment set up
20  ! ------------------
21  ! Module use
22  USE type_kinds, ONLY: long, double
24  USE odas_define, ONLY: odas_type
25  USE odps_define, ONLY: odps_type
26  USE odssu_define, ONLY: odssu_type
27  ! Disable implicit typing
28  IMPLICIT NONE
29 
30  ! ------------
31  ! Visibilities
32  ! ------------
33  ! Everything private by default
34  PRIVATE
35  ! Datatypes
36  PUBLIC :: taucoeff_type
37  ! Operators
38  PUBLIC :: ASSIGNMENT(=)
39  PUBLIC :: OPERATOR(.EQ.)
40  ! Procedures
41  PUBLIC :: taucoeff_associated
42  PUBLIC :: taucoeff_destroy
43  PUBLIC :: taucoeff_create
44  PUBLIC :: taucoeff_info
45 
46  ! -------------------
47  ! Procedure overloads
48  ! -------------------
49  INTERFACE ASSIGNMENT(=)
50  MODULE PROCEDURE taucoeff_assign
51  END INTERFACE
52 
53  INTERFACE OPERATOR(.EQ.)
54  MODULE PROCEDURE taucoeff_equal
55  END INTERFACE
56 
57 
58  ! -----------------
59  ! Module parameters
60  ! -----------------
61  ! RCS Id for the module
62  CHARACTER(*), PARAMETER :: module_rcs_id = &
63  '$Id: TauCoeff_Define.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
64  ! Message string length
65  INTEGER , PARAMETER :: ml = 256
66  ! Sensor ID string length
67  INTEGER , PARAMETER :: sl = 20
68 
69 
70  ! -----------------------
71  ! Derived type definition
72  ! -----------------------
73  TYPE :: taucoeff_type
74  ! Array dimensions
75  INTEGER :: n_sensors = 0 ! n
76  INTEGER :: n_odas = 0 ! I1
77  INTEGER :: n_odps = 0 ! I2
78  INTEGER :: n_odssu = 0 ! I3
79  INTEGER :: n_odzeeman = 0 ! I4
80  ! Arrays
81  INTEGER, ALLOCATABLE :: algorithm_id(:) ! n
82  INTEGER, ALLOCATABLE :: sensor_index(:) ! n
83  INTEGER, ALLOCATABLE :: sensor_loindex(:) ! n ; Local sensor index for a collection
84  ! of sensor using the same algorithm
85  INTEGER, ALLOCATABLE :: zsensor_loindex(:) ! n; Local sensor index for a collection of sensors
86  ! with channles requiring the Zeeman algorithm
87  ! Sensor Info: Sensor types and IDs
88  CHARACTER(SL), ALLOCATABLE :: sensor_id(:) ! n
89  INTEGER, ALLOCATABLE :: wmo_satellite_id(:) ! n
90  INTEGER, ALLOCATABLE :: wmo_sensor_id(:) ! n
91  INTEGER, ALLOCATABLE :: sensor_type(:) ! n
92 
93  ! Pointers
94  TYPE(odas_type), POINTER :: odas(:) => null() ! I1
95  TYPE(odps_type), POINTER :: odps(:) => null() ! I2
96  TYPE(odssu_type), POINTER :: odssu(:) => null() ! I3
97  TYPE(odps_type), POINTER :: odzeeman(:) => null() ! I4
98 
99  END TYPE taucoeff_type
100 
101 
102 CONTAINS
103 
104 
105 !--------------------------------------------------------------------------------
106 !:sdoc+:
107 ! NAME:
108 ! TauCoeff_Associated
109 !
110 ! PURPOSE:
111 ! Elemental Function to test the status of the allocatable and pointer
112 ! components of a TauCoeff structure.
113 !
114 ! CALLING SEQUENCE:
115 ! Is_Associated = TauCoeff_Associated( self )
116 !
117 ! OBJECTS:
118 ! self: TauCoeff structure which is to have its allocatable
119 ! and pointer components status tested.
120 ! UNITS: N/A
121 ! TYPE: TauCoeff_type
122 ! DIMENSION: Scalar
123 ! ATTRIBUTES: INTENT(IN)
124 !
125 ! FUNCTION RESULT:
126 ! Is_Associated: The return value is a logical value indicating the
127 ! status of the allocatable and pointer components.
128 ! .TRUE. - if ANY of the TauCoeff allocatable or
129 ! pointer members are in use.
130 ! .FALSE. - if ALL of the TauCoeff allocatable or
131 ! pointer members are not in use.
132 ! UNITS: N/A
133 ! TYPE: LOGICAL
134 ! DIMENSION: Scalar
135 !:sdoc-:
136 !--------------------------------------------------------------------------------
137 
138  ELEMENTAL FUNCTION taucoeff_associated( self ) RESULT( Is_Associated )
139  ! Arguments
140  TYPE(taucoeff_type), INTENT(IN) :: self
141  ! Function result
142  LOGICAL :: is_associated
143 
144  ! Test the structure associations
145  is_associated = &
146  ALLOCATED(self%Algorithm_ID ) .OR. &
147  ALLOCATED(self%Sensor_Index ) .OR. &
148  ALLOCATED(self%Sensor_LoIndex) .OR. &
149  ASSOCIATED(self%ODAS ) .OR. & ! Should this be tested?
150  ASSOCIATED(self%ODPS ) .OR. & ! Should this be tested?
151  ASSOCIATED(self%ODSSU ) .OR. & ! Should this be tested?
152  ASSOCIATED(self%ODZeeman ) ! Should this be tested?
153 
154  END FUNCTION taucoeff_associated
155 
156 
157 !------------------------------------------------------------------------------
158 !:sdoc+:
159 ! NAME:
160 ! TauCoeff_Destroy
161 !
162 ! PURPOSE:
163 ! Subroutine to re-initialize the TauCoeff data structures.
164 !
165 ! CALLING SEQUENCE:
166 ! CALL TauCoeff_Destroy( self, err_stat )
167 !
168 ! OBJECTS:
169 ! self: Re-initialized TauCoeff structure.
170 ! UNITS: N/A
171 ! TYPE: TauCoeff_type
172 ! DIMENSION: Scalar
173 ! ATTRIBUTES: INTENT(IN OUT)
174 !
175 ! OUTPUTS:
176 ! err_stat: The error status. The error codes are defined in the
177 ! Message_Handler module.
178 ! If == SUCCESS the object destruction was successful
179 ! == FAILURE an error occurred.
180 ! UNITS: N/A
181 ! TYPE: INTEGER
182 ! DIMENSION: Scalar
183 ! ATTRIBUTES: INTENT(OUT)
184 !
185 ! COMMENTS:
186 ! Note the INTENT on the TauCoeff object argument is IN OUT rather than
187 ! just OUT. This is necessary because the argument has pointer components
188 ! and may be defined upon input. To prevent memory leaks, the IN OUT
189 ! INTENT is a must.
190 !:sdoc-:
191 !------------------------------------------------------------------------------
192  SUBROUTINE taucoeff_destroy(self, err_stat)
193  ! Arguments
194  TYPE(taucoeff_type), INTENT(IN OUT) :: self
195  INTEGER, INTENT(OUT) :: err_stat
196  ! Local parameters
197  CHARACTER(*), PARAMETER :: routine_name = 'TauCoeff_Destroy'
198  ! Local variables
199  CHARACTER(ML) :: msg
200  INTEGER :: alloc_stat
201 
202  ! Set up
203  err_stat = success
204  ! ...If structure is unused, do nothing
205  IF ( .NOT. taucoeff_associated(self) ) RETURN
206 
207  ! Re-initialize the dimensions
208  self%n_Sensors = 0
209 
210  ! Deallocate the non-scalar components
211  DEALLOCATE( self%Algorithm_ID , &
212  self%Sensor_Index , &
213  self%Sensor_LoIndex , &
214  self%ZSensor_LoIndex , &
215  self%Sensor_ID , &
216  self%WMO_Satellite_ID, &
217  self%WMO_Sensor_ID , &
218  self%Sensor_Type , &
219  stat = alloc_stat )
220  IF ( alloc_stat /= 0 ) THEN
221  err_stat = failure
222  WRITE( msg, '( "Error deallocating. STAT = ", i0 )' ) alloc_stat
223  CALL display_message( routine_name, trim(msg), err_stat )
224  END IF
225 
226  ! Disassociate pointers
227  NULLIFY( self%ODAS, self%ODPS, self%ODSSU, self%ODZeeman )
228 
229  END SUBROUTINE taucoeff_destroy
230 
231 
232 !------------------------------------------------------------------------------
233 !:sdoc+:
234 ! NAME:
235 ! TauCoeff_Create
236 !
237 ! PURPOSE:
238 ! Subroutine to create an instance of the TauCoeff data structure.
239 !
240 ! CALLING SEQUENCE:
241 ! CALL TauCoeff_Create( self, n_Sensors, err_stat )
242 !
243 ! OBJECTS:
244 ! self: Instance of the TauCoeff structure.
245 ! UNITS: N/A
246 ! TYPE: TauCoeff_type
247 ! DIMENSION: Scalar
248 ! ATTRIBUTES: INTENT(IN OUT)
249 !
250 ! INPUTS:
251 ! n_Sensors: Number of sensors
252 ! Must be > 0.
253 ! UNITS: N/A
254 ! TYPE: INTEGER
255 ! DIMENSION: Scalar
256 ! ATTRIBUTES: INTENT(IN)
257 !
258 ! OUTPUTS:
259 ! err_stat: The error status. The error codes are defined in the
260 ! Message_Handler module.
261 ! If == SUCCESS the object creation was successful
262 ! == FAILURE an error occurred.
263 ! UNITS: N/A
264 ! TYPE: INTEGER
265 ! DIMENSION: Scalar
266 ! ATTRIBUTES: INTENT(OUT)
267 !
268 ! COMMENTS:
269 ! Note the INTENT on the TauCoeff object argument is IN OUT rather than
270 ! just OUT. This is necessary because the argument has pointer components
271 ! and may be defined upon input. To prevent memory leaks, the IN OUT
272 ! INTENT is a must.
273 !:sdoc-:
274 !------------------------------------------------------------------------------
275 
276  SUBROUTINE taucoeff_create(self, n_Sensors, err_stat)
277  ! Arguments
278  TYPE(taucoeff_type), INTENT(IN OUT) :: self
279  INTEGER, INTENT(IN) :: n_sensors
280  INTEGER, INTENT(OUT) :: err_stat
281  ! Local parameters
282  CHARACTER(*), PARAMETER :: routine_name = 'TauCoeff_Create'
283  ! Local variables
284  CHARACTER(ML) :: msg
285  INTEGER :: alloc_stat
286 
287  ! Set up
288  err_stat = success
289  ! ...Check input
290  IF ( taucoeff_associated( self ) ) THEN
291  CALL taucoeff_destroy( self, err_stat )
292  IF ( err_stat /= success ) THEN
293  msg = 'Error destroying TauCoeff prior to allocation.'
294  CALL display_message( routine_name, trim(msg), err_stat )
295  RETURN
296  END IF
297  END IF
298  IF ( n_sensors < 1 ) THEN
299  err_stat = failure
300  msg = 'n_Sensors must be > 0.'
301  CALL display_message( routine_name, trim(msg), err_stat )
302  RETURN
303  END IF
304 
305 
306  ! Perform the array allocation
307  ALLOCATE( self%Algorithm_ID( n_sensors ) , &
308  self%Sensor_Index( n_sensors ) , &
309  self%Sensor_LoIndex( n_sensors ) , &
310  self%ZSensor_LoIndex( n_sensors ) , &
311  self%Sensor_ID( n_sensors ) , &
312  self%WMO_Satellite_ID( n_sensors ), &
313  self%WMO_Sensor_ID( n_sensors ) , &
314  self%Sensor_Type( n_sensors ) , &
315  stat = alloc_stat )
316  IF ( alloc_stat /= 0 ) THEN
317  err_stat = failure
318  WRITE( msg, '("Error allocating TauCoeff. STAT = ",i0)' ) alloc_stat
319  CALL display_message( routine_name, trim(msg), err_stat )
320  RETURN
321  END IF
322 
323 
324  ! Initialise
325  ! ...Dimensions
326  self%n_Sensors = n_sensors
327  ! ...Arrays
328  self%Algorithm_ID = 0
329  self%Sensor_Index = 0
330  self%Sensor_LoIndex = 0
331  self%ZSensor_LoIndex = 0
332  self%Sensor_ID = ''
333  self%WMO_Satellite_ID = 0
334  self%WMO_Sensor_ID = 0
335  self%Sensor_Type = 0
336  ! ...Pointers (not required, but what the hell...)
337  NULLIFY( self%ODAS, self%ODPS, self%ODSSU, self%ODZeeman )
338 
339  END SUBROUTINE taucoeff_create
340 
341 !------------------------------------------------------------------------------
342 ! NAME:
343 ! TauCoeff_Info
344 !
345 ! PURPOSE:
346 ! Subroutine to return a string containing information about
347 ! a TauCoeff data structure.
348 !
349 ! CALLING SEQUENCE:
350 ! CALL TauCoeff_Info( self, info )
351 !
352 ! OBJECTS:
353 ! self: TauCoeff structure about which information is required.
354 ! UNITS: N/A
355 ! TYPE: TauCoeff_type
356 ! DIMENSION: Scalar
357 ! ATTRIBUTES: INTENT(IN)
358 !
359 ! OUTPUTS:
360 ! info: String containing information about the passed
361 ! TauCoeff data structure.
362 ! UNITS: N/A
363 ! TYPE: CHARACTER(*)
364 ! DIMENSION: Scalar
365 ! ATTRIBUTES: INTENT(OUT)
366 !------------------------------------------------------------------------------
367 
368  SUBROUTINE taucoeff_info( self, info )
369  ! Arguments
370  TYPE(taucoeff_type), INTENT(IN) :: self
371  CHARACTER(*), INTENT(OUT) :: info
372  ! Parameters
373  INTEGER, PARAMETER :: carriage_return = 13
374  INTEGER, PARAMETER :: linefeed = 10
375  ! Local variables
376  CHARACTER(2000) :: long_string
377 
378  ! Write the required info to the local string
379  WRITE( long_string, '( a, 2x, &
380  &"N_SENSORS=",i2,2x,&
381  &"N_ODAS=",i2,2x,&
382  &"N_ODPS=",i2,2x,&
383  &"N_ODSSU=",i2,2x,&
384  &"N_ODZeeman=",i2 )' ) &
385  achar(carriage_return)//achar(linefeed), &
386  self%n_Sensors, &
387  self%n_ODAS, &
388  self%n_ODPS, &
389  self%n_ODSSU, &
390  self%n_ODZeeman
391 
392  ! Trim the output based on the
393  ! dummy argument string length
394  info = long_string(1:min( len(info), len_trim( long_string ) ))
395 
396  END SUBROUTINE taucoeff_info
397 
398 !------------------------------------------------------------------------------
399 !
400 ! NAME:
401 ! TauCoeff_Assign
402 !
403 ! PURPOSE:
404 ! Subroutine to copy valid TauCoeff structures. Used in ASSIGNMENT(=)
405 ! interface block.
406 !
407 ! CALLING SEQUENCE:
408 ! CALL TauCoeff_Assign( copy, original )
409 !
410 ! or
411 !
412 ! copy = original
413 !
414 ! OBJECTS:
415 ! copy: Destination structure for copy.
416 ! UNITS: N/A
417 ! TYPE: TauCoeff_type
418 ! DIMENSION: Scalar
419 ! ATTRIBUTES: INTENT(IN OUT)
420 !
421 ! original: Structure to be copied.
422 ! UNITS: N/A
423 ! TYPE: TauCoeff_type
424 ! DIMENSION: Scalar
425 ! ATTRIBUTES: INTENT(IN)
426 !
427 ! COMMENTS:
428 ! Note the INTENT on the TauCoeff copy argument is IN OUT rather than
429 ! just OUT. This is necessary because the argument may be defined upon
430 ! input. To prevent memory leaks, the IN OUT INTENT is a must.
431 !
432 !------------------------------------------------------------------------------
433 
434  SUBROUTINE taucoeff_assign( copy, original )
435  ! Arguments
436  TYPE(TauCoeff_type), INTENT(IN OUT) :: copy
437  TYPE(TauCoeff_type), INTENT(IN) :: original
438  ! Parameters
439  CHARACTER(*), PARAMETER :: ROUTINE_NAME = 'TauCoeff_Assign'
440  ! Variables
441  INTEGER :: err_stat
442 
443  ! Destroy the output structure
444  CALL taucoeff_destroy( copy, err_stat )
445  IF ( err_stat /= success ) THEN
446  CALL display_message( routine_name, 'Output TauCoeff re-init failed', err_stat )
447  RETURN
448  END IF
449 
450  ! If input structure not used, do nothing
451  IF ( .NOT. taucoeff_associated( original ) ) RETURN
452 
453  ! Create the output structure
454  CALL taucoeff_create( copy, original%n_Sensors, err_stat )
455  IF ( err_stat /= success ) THEN
456  CALL display_message( routine_name, 'Output TauCoeff allocation failed', err_stat )
457  RETURN
458  END IF
459 
460  ! Copy array data
461  copy%Algorithm_ID = original%Algorithm_ID
462  copy%Sensor_Index = original%Sensor_Index
463  copy%Sensor_LoIndex = original%Sensor_LoIndex
464  copy%ZSensor_LoIndex = original%ZSensor_LoIndex
465  copy%Sensor_ID = original%Sensor_ID
466  copy%WMO_Satellite_ID = original%WMO_Satellite_ID
467  copy%WMO_Sensor_ID = original%WMO_Sensor_ID
468  copy%Sensor_Type = original%Sensor_Type
469 
470  ! Set pointers
471  IF ( ASSOCIATED(original%ODAS) ) copy%ODAS => original%ODAS
472  IF ( ASSOCIATED(original%ODPS) ) copy%ODPS => original%ODPS
473  IF ( ASSOCIATED(original%ODSSU) ) copy%ODSSU => original%ODSSU
474  IF ( ASSOCIATED(original%ODZeeman) ) copy%ODZeeman => original%ODZeeman
475 
476  END SUBROUTINE taucoeff_assign
477 
478 !------------------------------------------------------------------------------
479 !
480 ! NAME:
481 ! TauCoeff_Equal
482 !
483 ! PURPOSE:
484 ! Elemental function to test the equality of two TauCoeff structures.
485 ! Used in OPERATOR(.EQ.) interface block.
486 !
487 ! CALLING SEQUENCE:
488 ! is_equal = TauCoeff_Equal( x, y )
489 !
490 ! or
491 !
492 ! IF ( x == y ) THEN
493 ! ...
494 ! END IF
495 !
496 ! OBJECTS:
497 ! x, y: Two TauCoeff structures to be compared.
498 ! UNITS: N/A
499 ! TYPE: TauCoeff_type
500 ! DIMENSION: Scalar
501 ! ATTRIBUTES: INTENT(IN)
502 !
503 ! FUNCTION RESULT:
504 ! is_equal: Logical value indicating whether the inputs are equal.
505 ! UNITS: N/A
506 ! TYPE: LOGICAL
507 ! DIMENSION: Same as inputs.
508 !
509 !------------------------------------------------------------------------------
510 
511  ELEMENTAL FUNCTION taucoeff_equal( x, y ) RESULT( is_equal )
512  ! Arguments
513  TYPE(taucoeff_type), INTENT(IN) :: x, y
514  ! Function result
515  LOGICAL :: is_equal
516 
517  ! Setup
518  is_equal = .false.
519 
520  ! Check dimensions
521  IF ( (x%n_Sensors /= y%n_Sensors) .OR. &
522  (x%n_ODAS /= y%n_ODAS ) .OR. &
523  (x%n_ODPS /= y%n_ODPS ) .OR. &
524  (x%n_ODSSU /= y%n_ODSSU ) .OR. &
525  (x%n_ODZeeman /= y%n_ODZeeman ) ) RETURN
526 
527  ! Check arrays
528  IF ( any(x%Algorithm_ID /= y%Algorithm_ID ) .OR. &
529  any(x%Sensor_Index /= y%Sensor_Index ) .OR. &
530  any(x%Sensor_LoIndex /= y%Sensor_LoIndex) .OR. &
531  any(x%ZSensor_LoIndex /= y%ZSensor_LoIndex) .OR. &
532  any(x%Sensor_ID /= y%Sensor_ID) .OR. &
533  any(x%WMO_Satellite_ID /= y%WMO_Satellite_ID) .OR. &
534  any(x%WMO_Sensor_ID /= y%WMO_Sensor_ID) .OR. &
535  any(x%Sensor_Type /= y%Sensor_Type) ) RETURN
536 
537  ! Check pointers
538  ! .... ?
539  ! Call individual ODAS_Equal, ODPS_Equal and ODSSU_Equal functions?
540  ! If so, they must be elemental also!
541 
542  ! If we get here, everything is equal!
543  is_equal = .true.
544 
545  END FUNCTION taucoeff_equal
546 
547 END MODULE taucoeff_define
integer, parameter, public failure
elemental logical function taucoeff_equal(x, y)
integer, parameter sl
subroutine, public taucoeff_create(self, n_Sensors, err_stat)
integer, parameter, public long
Definition: Type_Kinds.f90:76
elemental logical function, public taucoeff_associated(self)
subroutine, public taucoeff_destroy(self, err_stat)
integer, parameter, public double
Definition: Type_Kinds.f90:106
character(*), parameter module_rcs_id
Definition: RTV_Define.f90:67
integer, parameter ml
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
subroutine, public taucoeff_info(self, info)
subroutine taucoeff_assign(copy, original)
#define min(a, b)
Definition: mosaic_util.h:32
integer, parameter, public success