FV3 Bundle
CRTM_ChannelInfo_Define.f90
Go to the documentation of this file.
1 !
2 ! CRTM_ChannelInfo_Define
3 !
4 ! Module defining the CRTM ChannelInfo data structure and containing
5 ! routines to manipulate it.
6 !
7 !
8 ! CREATION HISTORY:
9 ! Written by: Paul van Delst, 13-May-2004
10 ! paul.vandelst@noaa.gov
11 !
12 
14 
15  ! -----------------
16  ! Environment setup
17  ! -----------------
18  ! Intrinsic modules
19  USE iso_fortran_env , ONLY: output_unit
20  ! Module use
22  USE file_utility , ONLY: file_open
23  USE crtm_parameters , ONLY: strlen
27  USE sort_utility , ONLY: insertionsort
28  ! Disable implicit typing
29  IMPLICIT NONE
30 
31 
32  ! ------------
33  ! Visibilities
34  ! ------------
35  ! Everything private by default
36  PRIVATE
37  ! Structure definition
38  PUBLIC :: crtm_channelinfo_type
39  ! Operators
40  PUBLIC :: OPERATOR(==)
41  ! Structure procedures
43  PUBLIC :: crtm_channelinfo_destroy
44  PUBLIC :: crtm_channelinfo_create
45  PUBLIC :: crtm_channelinfo_inspect
49  PUBLIC :: crtm_channelinfo_subset
50 
51 
52  ! ---------------------
53  ! Procedure overloading
54  ! ---------------------
55  INTERFACE OPERATOR(==)
56  MODULE PROCEDURE crtm_channelinfo_equal
57  END INTERFACE OPERATOR(==)
58 
59 
60  ! -----------------
61  ! Module parameters
62  ! -----------------
63  ! Version Id for the module
64  CHARACTER(*), PARAMETER :: module_version_id = &
65  '$Id: CRTM_ChannelInfo_Define.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
66  ! Message string length
67  INTEGER, PARAMETER :: ml = 256
68 
69 
70  ! --------------------------------
71  ! ChannelInfo data type definition
72  ! --------------------------------
73  !:tdoc+:
75  ! Allocation indicator
76  LOGICAL :: is_allocated = .false.
77  ! Dimensions
78  INTEGER :: n_channels = 0 ! L dimension
79  ! Scalar data
80  CHARACTER(STRLEN) :: sensor_id = ''
81  INTEGER :: sensor_type = invalid_sensor
82  INTEGER :: wmo_satellite_id = invalid_wmo_satellite_id
83  INTEGER :: wmo_sensor_id = invalid_wmo_sensor_id
84  INTEGER :: sensor_index = 0
85  ! Array data
86  LOGICAL, ALLOCATABLE :: process_channel(:) ! L
87  INTEGER, ALLOCATABLE :: sensor_channel(:) ! L
88  INTEGER, ALLOCATABLE :: channel_index(:) ! L
89  END TYPE crtm_channelinfo_type
90  !:tdoc-:
91 
92 
93 CONTAINS
94 
95 
96 !################################################################################
97 !################################################################################
98 !## ##
99 !## ## PUBLIC MODULE ROUTINES ## ##
100 !## ##
101 !################################################################################
102 !################################################################################
103 
104 !--------------------------------------------------------------------------------
105 !:sdoc+:
106 !
107 ! NAME:
108 ! CRTM_ChannelInfo_Associated
109 !
110 ! PURPOSE:
111 ! Elemental function to test the status of the allocatable components
112 ! of a CRTM ChannelInfo object.
113 !
114 ! CALLING SEQUENCE:
115 ! Status = CRTM_ChannelInfo_Associated( ChannelInfo )
116 !
117 ! OBJECTS:
118 ! ChannelInfo: ChannelInfo object which is to have its member's
119 ! status tested.
120 ! UNITS: N/A
121 ! TYPE: TYPE(CRTM_ChannelInfo_type)
122 ! DIMENSION: Scalar or any rank
123 ! ATTRIBUTES: INTENT(IN)
124 !
125 ! FUNCTION RESULT:
126 ! Status: The return value is a logical value indicating the
127 ! status of the ChannelInfo members.
128 ! .TRUE. - if the array components are allocated.
129 ! .FALSE. - if the array components are not allocated.
130 ! UNITS: N/A
131 ! TYPE: LOGICAL
132 ! DIMENSION: Same as input ChannelInfo argument
133 !
134 !:sdoc-:
135 !--------------------------------------------------------------------------------
136 
137  ELEMENTAL FUNCTION crtm_channelinfo_associated( ChannelInfo ) RESULT( Status )
138  TYPE(crtm_channelinfo_type), INTENT(IN) :: channelinfo
139  LOGICAL :: status
140  status = channelinfo%Is_Allocated
141  END FUNCTION crtm_channelinfo_associated
142 
143 
144 !--------------------------------------------------------------------------------
145 !:sdoc+:
146 !
147 ! NAME:
148 ! CRTM_ChannelInfo_Destroy
149 !
150 ! PURPOSE:
151 ! Elemental subroutine to re-initialize CRTM ChannelInfo objects.
152 !
153 ! CALLING SEQUENCE:
154 ! CALL CRTM_ChannelInfo_Destroy( ChannelInfo )
155 !
156 ! OBJECTS:
157 ! ChannelInfo: Re-initialized ChannelInfo object.
158 ! UNITS: N/A
159 ! TYPE: TYPE(CRTM_ChannelInfo_type)
160 ! DIMENSION: Scalar or any rank
161 ! ATTRIBUTES: INTENT(OUT)
162 !
163 !:sdoc-:
164 !--------------------------------------------------------------------------------
165 
166  ELEMENTAL SUBROUTINE crtm_channelinfo_destroy( ChannelInfo )
167  TYPE(crtm_channelinfo_type), INTENT(OUT) :: channelinfo
168  channelinfo%Is_Allocated = .false.
169  channelinfo%n_Channels = 0
170  END SUBROUTINE crtm_channelinfo_destroy
171 
172 
173 !--------------------------------------------------------------------------------
174 !
175 ! NAME:
176 ! CRTM_ChannelInfo_Create
177 !
178 ! PURPOSE:
179 ! Elemental subroutine to create an instance of a CRTM ChannelInfo
180 ! object.
181 !
182 ! CALLING SEQUENCE:
183 ! CALL CRTM_ChannelInfo_Create( ChannelInfo, n_Channels )
184 !
185 ! OBJECTS:
186 ! ChannelInfo: ChannelInfo object.
187 ! UNITS: N/A
188 ! TYPE: TYPE(CRTM_ChannelInfo_type)
189 ! DIMENSION: Scalar or any rank
190 ! ATTRIBUTES: INTENT(OUT)
191 !
192 ! INPUTS:
193 ! n_Channels: The number of channels in the ChannelInfo structure.
194 ! Must be > 0.
195 ! UNITS: N/A
196 ! TYPE: INTEGER
197 ! DIMENSION: Conformable with ChannelInfo argument
198 ! ATTRIBUTES: INTENT(IN)
199 !
200 !:sdoc-:
201 !--------------------------------------------------------------------------------
202 
203  ELEMENTAL SUBROUTINE crtm_channelinfo_create( &
204  ChannelInfo, &
205  n_Channels )
206  ! Arguments
207  TYPE(crtm_channelinfo_type), INTENT(OUT) :: channelinfo
208  INTEGER, INTENT(IN) :: n_channels
209  ! Local variables
210  INTEGER :: alloc_stat
211 
212  ! Check input
213  IF ( n_channels < 1 ) RETURN
214 
215 
216  ! Perform the allocations.
217  ALLOCATE( channelinfo%Process_Channel( n_channels ), &
218  channelinfo%Sensor_Channel( n_channels ), &
219  channelinfo%Channel_Index( n_channels ), &
220  stat = alloc_stat )
221  IF ( alloc_stat /= 0 ) RETURN
222 
223 
224  ! Initialise
225  ! ...Dimensions
226  channelinfo%n_Channels = n_channels
227  ! ...Arrays
228  channelinfo%Process_Channel = .true.
229  channelinfo%Sensor_Channel = 0
230  channelinfo%Channel_Index = 0
231 
232 
233  ! Set allocation indicator
234  channelinfo%Is_Allocated = .true.
235 
236  END SUBROUTINE crtm_channelinfo_create
237 
238 
239 !--------------------------------------------------------------------------------
240 !:sdoc+:
241 !
242 ! NAME:
243 ! CRTM_ChannelInfo_Inspect
244 !
245 ! PURPOSE:
246 ! Subroutine to print the contents of a CRTM ChannelInfo object
247 ! to stdout.
248 !
249 ! CALLING SEQUENCE:
250 ! CALL CRTM_ChannelInfo_Inspect( chInfo, Unit=unit )
251 !
252 ! OBJECTS:
253 ! chInfo: ChannelInfo object to display.
254 ! UNITS: N/A
255 ! TYPE: TYPE(CRTM_ChannelInfo_type)
256 ! DIMENSION: Scalar
257 ! ATTRIBUTES: INTENT(IN)
258 !
259 ! OPTIONAL INPUTS:
260 ! Unit: Unit number for an already open file to which the output
261 ! will be written.
262 ! If the argument is specified and the file unit is not
263 ! connected, the output goes to stdout.
264 ! UNITS: N/A
265 ! TYPE: INTEGER
266 ! DIMENSION: Scalar
267 ! ATTRIBUTES: INTENT(IN), OPTIONAL
268 !
269 !:sdoc-:
270 !--------------------------------------------------------------------------------
271 
272  SUBROUTINE crtm_channelinfo_inspect( chInfo, Unit )
273  ! Arguments
274  TYPE(crtm_channelinfo_type), INTENT(IN) :: chinfo
275  INTEGER, OPTIONAL, INTENT(IN) :: unit
276  ! Local variables
277  INTEGER :: fid
278  INTEGER :: i
279  CHARACTER(3) :: process
280 
281  ! Setup
282  fid = output_unit
283  IF ( PRESENT(unit) ) THEN
284  IF ( file_open(unit) ) fid = unit
285  END IF
286 
287 
288  WRITE(fid,'(1x,"ChannelInfo OBJECT")')
289  WRITE(fid,'(3x,"n_Channels :",1x,i0)') chinfo%n_Channels
290  WRITE(fid,'(3x,"Sensor Id :",1x,a )') trim(chinfo%Sensor_ID)
291  WRITE(fid,'(3x,"Sensor_Type :",1x,i0)') chinfo%Sensor_Type
292  WRITE(fid,'(3x,"WMO_Satellite_ID :",1x,i0)') chinfo%WMO_Satellite_ID
293  WRITE(fid,'(3x,"WMO_Sensor_ID :",1x,i0)') chinfo%WMO_Sensor_ID
294  WRITE(fid,'(3x,"Sensor_Index :",1x,i0)') chinfo%Sensor_Index
295  IF ( .NOT. crtm_channelinfo_associated(chinfo) ) RETURN
296  WRITE(fid,'(3x,"Channel# Index Process?")')
297  DO i = 1, chinfo%n_Channels
298  IF ( chinfo%Process_Channel(i) ) THEN
299  process = 'yes'
300  ELSE
301  process = 'no'
302  END IF
303  WRITE(fid,'(4x,i5,7x,i5,8x,a)') &
304  chinfo%Sensor_Channel(i), chinfo%Channel_Index(i), process
305  END DO
306  END SUBROUTINE crtm_channelinfo_inspect
307 
308 
309 !--------------------------------------------------------------------------------
310 !:sdoc+:
311 !
312 ! NAME:
313 ! CRTM_ChannelInfo_n_Channels
314 !
315 ! PURPOSE:
316 ! Elemental function to return the number of channels flagged for
317 ! processing in a ChannelInfo object.
318 !
319 ! CALLING SEQUENCE:
320 ! n_Channels = CRTM_ChannelInfo_n_Channels( ChannelInfo )
321 !
322 ! OBJECTS:
323 ! ChannelInfo: ChannelInfo object which is to have its processed
324 ! channels counted.
325 ! UNITS: N/A
326 ! TYPE: TYPE(CRTM_ChannelInfo_type)
327 ! DIMENSION: Scalar or any rank
328 ! ATTRIBUTES: INTENT(IN)
329 !
330 ! FUNCTION RESULT:
331 ! n_Channels: The number of channels to be processed in the ChannelInfo
332 ! object.
333 ! UNITS: N/A
334 ! TYPE: INTEGER
335 ! DIMENSION: Same as input ChannelInfo argument.
336 !
337 !:sdoc-:
338 !--------------------------------------------------------------------------------
339 
340  ELEMENTAL FUNCTION crtm_channelinfo_n_channels( ChannelInfo ) RESULT( n_Channels )
341  TYPE(crtm_channelinfo_type), INTENT(IN) :: channelinfo
342  INTEGER :: n_channels
343  n_channels = count(channelinfo%Process_Channel)
344  END FUNCTION crtm_channelinfo_n_channels
345 
346 
347 !--------------------------------------------------------------------------------
348 !:sdoc+:
349 !
350 ! NAME:
351 ! CRTM_ChannelInfo_Channels
352 !
353 ! PURPOSE:
354 ! Pure function to return the list of channels to be processed in a
355 ! ChannelInfo object.
356 !
357 ! CALLING SEQUENCE:
358 ! Channels = CRTM_ChannelInfo_Channels( ChannelInfo )
359 !
360 ! OBJECTS:
361 ! ChannelInfo: ChannelInfo object which is to have its channel list queried.
362 ! UNITS: N/A
363 ! TYPE: TYPE(CRTM_ChannelInfo_type)
364 ! DIMENSION: Scalar
365 ! ATTRIBUTES: INTENT(IN)
366 !
367 ! FUNCTION RESULT:
368 ! Channels: The list of channels to be processed in the ChannelInfo
369 ! object.
370 ! UNITS: N/A
371 ! TYPE: INTEGER
372 ! DIMENSION: Rank-1
373 !
374 !:sdoc-:
375 !--------------------------------------------------------------------------------
376 
377  PURE FUNCTION crtm_channelinfo_channels( ChannelInfo ) RESULT( Channels )
378  TYPE(crtm_channelinfo_type), INTENT(IN) :: channelinfo
379  INTEGER :: channels(crtm_channelinfo_n_channels(channelinfo))
380  channels = pack(channelinfo%Sensor_Channel, mask=channelinfo%Process_Channel)
381  END FUNCTION crtm_channelinfo_channels
382 
383 
384 !--------------------------------------------------------------------------------
385 !:sdoc+:
386 !
387 ! NAME:
388 ! CRTM_ChannelInfo_Subset
389 !
390 ! PURPOSE:
391 ! Function to specify a channel subset for processing in the CRTM.
392 ! By default, ALL channels are processed. This function allows the
393 ! list of channels that are to be processed to be altered.
394 !
395 ! CALLING SEQUENCE:
396 ! Error_Status = CRTM_ChannelInfo_Subset( ChannelInfo , &
397 ! Channel_Subset, &
398 ! Reset )
399 !
400 ! OBJECTS:
401 ! ChannelInfo: Valid ChannelInfo object for which a channel subset is
402 ! to be specified.
403 ! UNITS: N/A
404 ! TYPE: TYPE(CRTM_ChannelInfo_type)
405 ! DIMENSION: Scalar
406 ! ATTRIBUTES: INTENT(IN OUT)
407 !
408 ! OPTIONAL INPUTS:
409 ! Channel_Subset: An integer array containing the subset list of channels.
410 ! Future calls to the CRTM main functions using the passed
411 ! ChannelInfo object will process ONLY the channels
412 ! specified in this list.
413 ! *** NOTE: This argument is ignored if the Reset optional
414 ! *** argument is specified with a .TRUE. value.
415 ! UNITS: N/A
416 ! TYPE: INTEGER
417 ! DIMENSION: Rank-1
418 ! ATTRIBUTES: INTENT(IN), OPTIONAL
419 !
420 ! Reset: Logical flag to reset the ChannelInfo object channel
421 ! processing subset to ALL channels.
422 ! If == .TRUE. Future calls to the CRTM main functions using
423 ! the passed ChannelInfo object will process
424 ! ALL the channels
425 ! == .FALSE. Procedure execution is equivalent to the Reset
426 ! argument not being specified at all.
427 ! UNITS: N/A
428 ! TYPE: LOGICAL
429 ! DIMENSION: Scalar
430 ! ATTRIBUTES: INTENT(IN), OPTIONAL
431 !
432 ! FUNCTION RESULT:
433 ! Error_Status: The return value is an integer defining the error status.
434 ! The error codes are defined in the Message_Handler module.
435 ! If == SUCCESS the channel subset setting was sucessful
436 ! == FAILURE an error occurred
437 ! UNITS: N/A
438 ! TYPE: INTEGER
439 ! DIMENSION: Scalar
440 !
441 ! COMMENTS:
442 ! - The ChannelInfo object can be modified by this procedure.
443 ! - An error in this procedure will DISABLE processing for ALL channels.
444 !
445 !:sdoc-:
446 !--------------------------------------------------------------------------------
447 
448  FUNCTION crtm_channelinfo_subset( &
449  ChannelInfo , & ! In/output
450  Channel_Subset, & ! Optional input
451  Reset ) & ! Optional input
452  result( err_stat )
453  ! Arguments
454  TYPE(crtm_channelinfo_type), INTENT(IN OUT) :: channelinfo
455  INTEGER, OPTIONAL, INTENT(IN) :: channel_subset(:)
456  LOGICAL, OPTIONAL, INTENT(IN) :: reset
457  ! Function result
458  INTEGER :: err_stat
459  ! Local parameters
460  CHARACTER(*), PARAMETER :: routine_name = 'CRTM_ChannelInfo_Subset'
461  ! Local variables
462  CHARACTER(ML) :: msg
463  INTEGER :: alloc_stat
464  INTEGER :: i, j, n
465  INTEGER :: channel_idx(channelinfo%n_channels)
466  INTEGER, ALLOCATABLE :: subset_idx(:)
467 
468  ! Setup
469  err_stat = success
470 
471  ! Process Reset option first
472  IF ( PRESENT(reset) ) THEN
473  IF ( reset ) THEN
474  channelinfo%Process_Channel = .true.
475  RETURN
476  END IF
477  END IF
478 
479  ! Process channel list
480  IF ( PRESENT(channel_subset) ) THEN
481  n = SIZE(channel_subset)
482  ! Default: turn off all processing
483  channelinfo%Process_Channel = .false.
484  ! No channels specified
485  IF ( n == 0 ) RETURN
486  ! Too many specified
487  IF ( n > channelinfo%n_Channels ) THEN
488  err_stat = failure
489  msg = 'Specified Channel_Subset contains too many channels!'
490  CALL display_message( routine_name, msg, err_stat ); RETURN
491  END IF
492  ! Invalid channels specified
493  IF ( any(channel_subset < minval(channelinfo%Sensor_Channel)) .OR. &
494  any(channel_subset > maxval(channelinfo%Sensor_Channel)) ) THEN
495  err_stat = failure
496  msg = 'Specified Channel_Subset contains invalid channels!'
497  CALL display_message( routine_name, msg, err_stat ); RETURN
498  END IF
499  ! Allocate subset index array
500  ALLOCATE( subset_idx(n),stat=alloc_stat )
501  IF ( alloc_stat /= 0 ) THEN
502  err_stat = failure
503  msg = 'Error allocating subset_idx array'
504  CALL display_message( routine_name, msg, err_stat ); RETURN
505  END IF
506  ! Turn on processing for selected channels
507  CALL insertionsort( channelinfo%Sensor_Channel, channel_idx )
508  CALL insertionsort( channel_subset, subset_idx )
509  j = 1
510  channel_loop: DO i = 1, channelinfo%n_Channels
511  IF ( channel_subset(subset_idx(j)) == channelinfo%Sensor_Channel(channel_idx(i)) ) THEN
512  channelinfo%Process_Channel(channel_idx(i)) = .true.
513  j = j + 1
514  IF ( j > n ) EXIT channel_loop
515  END IF
516  END DO channel_loop
517  ! Clean up
518  DEALLOCATE( subset_idx )
519  END IF
520 
521  END FUNCTION crtm_channelinfo_subset
522 
523 
524 !--------------------------------------------------------------------------------
525 !:sdoc+:
526 !
527 ! NAME:
528 ! CRTM_ChannelInfo_DefineVersion
529 !
530 ! PURPOSE:
531 ! Subroutine to return the module version information.
532 !
533 ! CALLING SEQUENCE:
534 ! CALL CRTM_ChannelInfo_DefineVersion( Id )
535 !
536 ! OUTPUTS:
537 ! Id: Character string containing the version Id information
538 ! for the module.
539 ! UNITS: N/A
540 ! TYPE: CHARACTER(*)
541 ! DIMENSION: Scalar
542 ! ATTRIBUTES: INTENT(OUT)
543 !
544 !:sdoc-:
545 !--------------------------------------------------------------------------------
546 
547  SUBROUTINE crtm_channelinfo_defineversion( Id )
548  CHARACTER(*), INTENT(OUT) :: id
549  id = module_version_id
550  END SUBROUTINE crtm_channelinfo_defineversion
551 
552 
553 !##################################################################################
554 !##################################################################################
555 !## ##
556 !## ## PRIVATE MODULE ROUTINES ## ##
557 !## ##
558 !##################################################################################
559 !##################################################################################
560 
561 !------------------------------------------------------------------------------
562 !
563 ! NAME:
564 ! CRTM_ChannelInfo_Equal
565 !
566 ! PURPOSE:
567 ! Elemental function to test the equality of two CRTM ChannelInfo objects.
568 ! Used in OPERATOR(==) interface block.
569 !
570 ! CALLING SEQUENCE:
571 ! is_equal = CRTM_ChannelInfo_Equal( x, y )
572 !
573 ! or
574 !
575 ! IF ( x == y ) THEN
576 ! ...
577 ! END IF
578 !
579 ! OBJECTS:
580 ! x, y: Two CRTM ChannelInfo objects to be compared.
581 ! UNITS: N/A
582 ! TYPE: TYPE(CRTM_ChannelInfo_type)
583 ! DIMENSION: Scalar or any rank
584 ! ATTRIBUTES: INTENT(IN)
585 !
586 ! FUNCTION RESULT:
587 ! is_equal: Logical value indicating whether the inputs are equal.
588 ! UNITS: N/A
589 ! TYPE: LOGICAL
590 ! DIMENSION: Same as inputs.
591 !
592 !------------------------------------------------------------------------------
593 
594  ELEMENTAL FUNCTION crtm_channelinfo_equal( x, y ) RESULT( is_equal )
595  TYPE(crtm_channelinfo_type) , INTENT(IN) :: x, y
596  LOGICAL :: is_equal
597 
598  ! Set up
599  is_equal = .false.
600 
601  ! Check the object association status
602  IF ( (.NOT. crtm_channelinfo_associated(x)) .OR. &
603  (.NOT. crtm_channelinfo_associated(y)) ) RETURN
604 
605  ! Check contents
606  ! ...Dimensions
607  IF ( x%n_Channels /= y%n_Channels ) RETURN
608  ! ...Data
609  IF ( (x%Sensor_ID == y%Sensor_ID ) .AND. &
610  (x%Sensor_Type == y%Sensor_Type ) .AND. &
611  (x%WMO_Satellite_ID == y%WMO_Satellite_ID) .AND. &
612  (x%WMO_Sensor_ID == y%WMO_Sensor_ID ) .AND. &
613  (x%Sensor_Index == y%Sensor_Index ) .AND. &
614  all(x%Process_Channel .EQV. y%Process_Channel) .AND. &
615  all(x%Sensor_Channel == y%Sensor_Channel ) .AND. &
616  all(x%Channel_Index == y%Channel_Index ) ) &
617  is_equal = .true.
618 
619  END FUNCTION crtm_channelinfo_equal
620 
621 END MODULE crtm_channelinfo_define
integer, parameter, public failure
integer function, public crtm_channelinfo_subset(ChannelInfo, Channel_Subset, Reset)
integer, parameter, public strlen
character(*), parameter module_version_id
elemental subroutine, public crtm_channelinfo_destroy(ChannelInfo)
subroutine, public crtm_channelinfo_inspect(chInfo, Unit)
subroutine, public crtm_channelinfo_defineversion(Id)
elemental logical function crtm_channelinfo_equal(x, y)
elemental logical function, public crtm_channelinfo_associated(ChannelInfo)
elemental subroutine, public crtm_channelinfo_create(ChannelInfo, n_Channels)
pure integer function, dimension(crtm_channelinfo_n_channels(channelinfo)), public crtm_channelinfo_channels(ChannelInfo)
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
integer, parameter, public invalid_wmo_satellite_id
integer, parameter, public invalid_sensor
integer, parameter, public invalid_wmo_sensor_id
elemental integer function, public crtm_channelinfo_n_channels(ChannelInfo)
integer, parameter, public success