FV3 Bundle
ACCoeff_Define.f90
Go to the documentation of this file.
1 !
2 ! ACCoeff_Define
3 !
4 ! Module defining the ACCoeff data structure and containing routines to
5 ! manipulate it.
6 !
7 ! CREATION HISTORY:
8 ! Written by: Paul van Delst, 25-Jan-2011
9 ! paul.vandelst@noaa.gov
10 !
11 
13 
14  ! ------------------
15  ! Environment set up
16  ! ------------------
17  ! Module use
18  USE type_kinds, ONLY: long, double
20  USE compare_float_numbers, ONLY: OPERATOR(.equalto.)
21  USE subset_define , ONLY: subset_type , &
23  subset_getvalue , &
27  ! Disable implicit typing
28  IMPLICIT NONE
29 
30 
31  ! ------------
32  ! Visibilities
33  ! ------------
34  ! Everything private by default
35  PRIVATE
36  ! Datatypes
37  PUBLIC :: accoeff_type
38  ! Operators
39  PUBLIC :: OPERATOR(==)
40  ! Procedures
41  PUBLIC :: accoeff_associated
42  PUBLIC :: accoeff_destroy
43  PUBLIC :: accoeff_create
44  PUBLIC :: accoeff_inspect
45  PUBLIC :: accoeff_validrelease
46  PUBLIC :: accoeff_info
47  PUBLIC :: accoeff_defineversion
48  PUBLIC :: accoeff_subset
49  PUBLIC :: accoeff_concat
50  PUBLIC :: accoeff_channelreindex
51 
52 
53  ! ---------------------
54  ! Procedure overloading
55  ! ---------------------
56  INTERFACE OPERATOR(==)
57  MODULE PROCEDURE accoeff_equal
58  END INTERFACE OPERATOR(==)
59 
60 
61  ! -----------------
62  ! Module parameters
63  ! -----------------
64  ! Version Id for the module
65  CHARACTER(*), PARAMETER :: module_version_id = &
66  '$Id: ACCoeff_Define.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
67  ! Literal constants
68  REAL(Double), PARAMETER :: zero = 0.0_double
69  REAL(Double), PARAMETER :: one = 1.0_double
70  ! Default message string length
71  INTEGER, PARAMETER :: ml = 512
72  ! Sensor id string length
73  INTEGER, PARAMETER :: sl = 20
74  ! Current valid release and version numbers
75  INTEGER, PARAMETER :: accoeff_release = 1
76  INTEGER, PARAMETER :: accoeff_version = 1
77 
78 
79  ! -----------------------
80  ! Derived type definition
81  ! -----------------------
82  TYPE :: accoeff_type
83  ! Allocation indicator
84  LOGICAL :: is_allocated = .false.
85  ! Release and version information
86  INTEGER(Long) :: release = accoeff_release
87  INTEGER(Long) :: version = accoeff_version
88  ! Dimensions
89  INTEGER(Long) :: n_fovs = 0 ! N
90  INTEGER(Long) :: n_channels = 0 ! L
91  ! Sensor info
92  CHARACTER(SL) :: sensor_id = ''
93  INTEGER(Long) :: wmo_satellite_id = invalid_wmo_satellite_id
94  INTEGER(Long) :: wmo_sensor_id = invalid_wmo_sensor_id
95  INTEGER(Long), ALLOCATABLE :: sensor_channel(:) ! L
96  ! Antenna correction coefficients
97  REAL(Double) , ALLOCATABLE :: a_earth(:,:) ! N x L
98  REAL(Double) , ALLOCATABLE :: a_space(:,:) ! N x L
99  REAL(Double) , ALLOCATABLE :: a_platform(:,:) ! N x L
100  END TYPE accoeff_type
101 
102 
103 CONTAINS
104 
105 
106 !################################################################################
107 !################################################################################
108 !## ##
109 !## ## PUBLIC MODULE ROUTINES ## ##
110 !## ##
111 !################################################################################
112 !################################################################################
113 
114 !--------------------------------------------------------------------------------
115 !:sdoc+:
116 !
117 ! NAME:
118 ! ACCoeff_Associated
119 !
120 ! PURPOSE:
121 ! Elemental function to test the status of the allocatable components
122 ! of the ACCoeff structure.
123 !
124 ! CALLING SEQUENCE:
125 ! Status = ACCoeff_Associated( ACCoeff )
126 !
127 ! OBJECTS:
128 ! ACCoeff: Structure which is to have its member's
129 ! status tested.
130 ! UNITS: N/A
131 ! TYPE: ACCoeff_type
132 ! DIMENSION: Scalar or any rank
133 ! ATTRIBUTES: INTENT(IN)
134 !
135 ! FUNCTION RESULT:
136 ! Status: The return value is a logical value indicating the
137 ! status of the ACCoeff members.
138 ! .TRUE. - if ANY of the ACCoeff allocatable members
139 ! are in use.
140 ! .FALSE. - if ALL of the ACCoeff allocatable members
141 ! are not in use.
142 ! UNITS: N/A
143 ! TYPE: LOGICAL
144 ! DIMENSION: Same as input
145 !
146 !:sdoc-:
147 !--------------------------------------------------------------------------------
148 
149  ELEMENTAL FUNCTION accoeff_associated( ACCoeff ) RESULT( Status )
150  TYPE(accoeff_type), INTENT(IN) :: accoeff
151  LOGICAL :: status
152  status = accoeff%Is_Allocated
153  END FUNCTION accoeff_associated
154 
155 
156 !--------------------------------------------------------------------------------
157 !:sdoc+:
158 !
159 ! NAME:
160 ! ACCoeff_Destroy
161 !
162 ! PURPOSE:
163 ! Elemental subroutine to re-initialize ACCoeff objects.
164 !
165 ! CALLING SEQUENCE:
166 ! CALL ACCoeff_Destroy( ACCoeff )
167 !
168 ! OBJECTS:
169 ! ACCoeff: Re-initialized ACCoeff structure.
170 ! UNITS: N/A
171 ! TYPE: ACCoeff_type
172 ! DIMENSION: Scalar or any rank
173 ! ATTRIBUTES: INTENT(OUT)
174 !
175 !:sdoc-:
176 !--------------------------------------------------------------------------------
177 
178  ELEMENTAL SUBROUTINE accoeff_destroy( ACCoeff )
179  TYPE(accoeff_type), INTENT(OUT) :: accoeff
180  accoeff%Is_Allocated = .false.
181  accoeff%n_FOVs = 0
182  accoeff%n_Channels = 0
183  accoeff%Sensor_Id = ''
184  accoeff%WMO_Satellite_ID = invalid_wmo_satellite_id
185  accoeff%WMO_Sensor_ID = invalid_wmo_sensor_id
186  END SUBROUTINE accoeff_destroy
187 
188 
189 !--------------------------------------------------------------------------------
190 !:sdoc+:
191 !
192 ! NAME:
193 ! ACCoeff_Create
194 !
195 ! PURPOSE:
196 ! Elemental subroutine to create an instance of an ACCoeff object.
197 !
198 ! CALLING SEQUENCE:
199 ! CALL ACCoeff_Create( ACCoeff , &
200 ! n_FOVs , &
201 ! n_Channels )
202 !
203 ! OBJECTS:
204 ! ACCoeff: ACCoeff object structure.
205 ! UNITS: N/A
206 ! TYPE: ACCoeff_type
207 ! DIMENSION: Scalar or any rank
208 ! ATTRIBUTES: INTENT(OUT)
209 !
210 ! INPUTS:
211 ! n_FOVs: Number of sensor fields-of-view (FOVs).
212 ! Must be > 0.
213 ! UNITS: N/A
214 ! TYPE: INTEGER
215 ! DIMENSION: Scalar
216 ! ATTRIBUTES: INTENT(IN)
217 !
218 ! n_Channels: Number of sensor channels.
219 ! Must be > 0.
220 ! UNITS: N/A
221 ! TYPE: INTEGER
222 ! DIMENSION: Scalar
223 ! ATTRIBUTES: INTENT(IN)
224 !
225 !:sdoc-:
226 !--------------------------------------------------------------------------------
227 
228  ELEMENTAL SUBROUTINE accoeff_create( &
229  ACCoeff , & ! Output
230  n_FOVs , & ! Input
231  n_Channels ) ! Input
232  ! Arguments
233  TYPE(accoeff_type), INTENT(OUT) :: accoeff
234  INTEGER , INTENT(IN) :: n_fovs
235  INTEGER , INTENT(IN) :: n_channels
236  ! Local variables
237  INTEGER :: alloc_stat
238 
239  ! Check input
240  IF ( n_fovs < 1 .OR. &
241  n_channels < 1 ) RETURN
242 
243  ! Perform the allocation
244  ALLOCATE( accoeff%Sensor_Channel( 1:n_channels ), &
245  accoeff%A_earth( 1:n_fovs, 1:n_channels ), &
246  accoeff%A_space( 1:n_fovs, 1:n_channels ), &
247  accoeff%A_platform( 1:n_fovs, 1:n_channels ), &
248  stat = alloc_stat )
249  IF ( alloc_stat /= 0 ) RETURN
250 
251 
252  ! Initialise
253  ! ...Dimensions
254  accoeff%n_FOVs = n_fovs
255  accoeff%n_Channels = n_channels
256  ! ...Arrays
257  accoeff%Sensor_Channel = 0
258  accoeff%A_earth = one
259  accoeff%A_space = zero
260  accoeff%A_platform = zero
261 
262 
263  ! Set allocation indicator
264  accoeff%Is_Allocated = .true.
265 
266  END SUBROUTINE accoeff_create
267 
268 
269 !--------------------------------------------------------------------------------
270 !:sdoc+:
271 !
272 ! NAME:
273 ! ACCoeff_Inspect
274 !
275 ! PURPOSE:
276 ! Subroutine to print the contents of a ACCoeff object to stdout.
277 !
278 ! CALLING SEQUENCE:
279 ! CALL ACCoeff_Inspect( ACCoeff )
280 !
281 ! OBJECTS:
282 ! ACCoeff: ACCoeff object to display.
283 ! UNITS: N/A
284 ! TYPE: ACCoeff_type
285 ! DIMENSION: Scalar
286 ! ATTRIBUTES: INTENT(IN)
287 !
288 !:sdoc-:
289 !--------------------------------------------------------------------------------
290 
291  SUBROUTINE accoeff_inspect( ACCoeff )
292  TYPE(accoeff_type), INTENT(IN) :: accoeff
293  WRITE(*,'(1x,"ACCoeff OBJECT")')
294  ! Release/version info
295  WRITE(*,'(3x,"Release.Version :",1x,i0,".",i0)') accoeff%Release, accoeff%Version
296  ! Dimensions
297  WRITE(*,'(3x,"n_FOVs :",1x,i0)') accoeff%n_FOVs
298  WRITE(*,'(3x,"n_Channels :",1x,i0)') accoeff%n_Channels
299  IF ( .NOT. accoeff_associated(accoeff) ) RETURN
300  ! Sensor info
301  WRITE(*,'(3x,"Sensor_Id :",1x,a )') trim(accoeff%Sensor_Id)
302  WRITE(*,'(3x,"WMO_Satellite_ID :",1x,i0)') accoeff%WMO_Satellite_ID
303  WRITE(*,'(3x,"WMO_Sensor_ID :",1x,i0)') accoeff%WMO_Sensor_ID
304  WRITE(*,'(3x,"Sensor_Channel :")')
305  WRITE(*,'(10(1x,i5,:))') accoeff%Sensor_Channel
306  ! Coefficient arrays
307  WRITE(*,'(3x,"A_earth :")')
308  WRITE(*,'(5(1x,es13.6,:))') accoeff%A_earth
309  WRITE(*,'(3x,"A_space :")')
310  WRITE(*,'(5(1x,es13.6,:))') accoeff%A_space
311  WRITE(*,'(3x,"A_platform :")')
312  WRITE(*,'(5(1x,es13.6,:))') accoeff%A_platform
313 
314  END SUBROUTINE accoeff_inspect
315 
316 
317 !----------------------------------------------------------------------------------
318 !:sdoc+:
319 !
320 ! NAME:
321 ! ACCoeff_ValidRelease
322 !
323 ! PURPOSE:
324 ! Function to check the ACCoeff Release value.
325 !
326 ! CALLING SEQUENCE:
327 ! IsValid = ACCoeff_ValidRelease( ACCoeff )
328 !
329 ! INPUTS:
330 ! ACCoeff: ACCoeff object for which the Release component
331 ! is to be checked.
332 ! UNITS: N/A
333 ! TYPE: ACCoeff_type
334 ! DIMENSION: Scalar
335 ! ATTRIBUTES: INTENT(IN)
336 !
337 ! FUNCTION RESULT:
338 ! IsValid: Logical value defining the release validity.
339 ! UNITS: N/A
340 ! TYPE: LOGICAL
341 ! DIMENSION: Scalar
342 !
343 !:sdoc-:
344 !----------------------------------------------------------------------------------
345 
346  FUNCTION accoeff_validrelease( ACCoeff ) RESULT( IsValid )
347  ! Arguments
348  TYPE(accoeff_type), INTENT(IN) :: accoeff
349  ! Function result
350  LOGICAL :: isvalid
351  ! Local parameters
352  CHARACTER(*), PARAMETER :: routine_name = 'ACCoeff_ValidRelease'
353  ! Local variables
354  CHARACTER(ML) :: msg
355 
356  ! Set up
357  isvalid = .true.
358 
359 
360  ! Check release is not too old
361  IF ( accoeff%Release < accoeff_release ) THEN
362  isvalid = .false.
363  WRITE( msg,'("An ACCoeff data update is needed. ", &
364  &"ACCoeff release is ",i0,". Valid release is ",i0,"." )' ) &
365  accoeff%Release, accoeff_release
366  CALL display_message( routine_name, msg, information )
367  RETURN
368  END IF
369 
370 
371  ! Check release is not too new
372  IF ( accoeff%Release > accoeff_release ) THEN
373  isvalid = .false.
374  WRITE( msg,'("An ACCoeff software update is needed. ", &
375  &"ACCoeff release is ",i0,". Valid release is ",i0,"." )' ) &
376  accoeff%Release, accoeff_release
377  CALL display_message( routine_name, msg, information )
378  RETURN
379  END IF
380 
381  END FUNCTION accoeff_validrelease
382 
383 
384 !--------------------------------------------------------------------------------
385 !:sdoc+:
386 !
387 ! NAME:
388 ! ACCoeff_Info
389 !
390 ! PURPOSE:
391 ! Subroutine to return a string containing version and dimension
392 ! information about a ACCoeff object.
393 !
394 ! CALLING SEQUENCE:
395 ! CALL ACCoeff_Info( ACCoeff, Info )
396 !
397 ! OBJECTS:
398 ! ACCoeff: ACCoeff object about which info is required.
399 ! UNITS: N/A
400 ! TYPE: ACCoeff_type
401 ! DIMENSION: Scalar
402 ! ATTRIBUTES: INTENT(IN)
403 !
404 ! OUTPUTS:
405 ! Info: String containing version and dimension information
406 ! about the ACCoeff object.
407 ! UNITS: N/A
408 ! TYPE: CHARACTER(*)
409 ! DIMENSION: Scalar
410 ! ATTRIBUTES: INTENT(OUT)
411 !
412 !:sdoc-:
413 !--------------------------------------------------------------------------------
414 
415  SUBROUTINE accoeff_info( ACCoeff, Info )
416  ! Arguments
417  TYPE(accoeff_type), INTENT(IN) :: accoeff
418  CHARACTER(*), INTENT(OUT) :: info
419  ! Parameters
420  INTEGER, PARAMETER :: carriage_return = 13
421  INTEGER, PARAMETER :: linefeed = 10
422  ! Local variables
423  CHARACTER(2000) :: long_string
424 
425  ! Write the required data to the local string
426  WRITE( long_string, &
427  '(a,1x,"ACCoeff RELEASE.VERSION: ",i2,".",i2.2,a,3x, &
428  &"N_FOVS=",i0,2x,&
429  &"N_CHANNELS=",i0 )' ) &
430  achar(carriage_return)//achar(linefeed), &
431  accoeff%Release, accoeff%Version, &
432  achar(carriage_return)//achar(linefeed), &
433  accoeff%n_FOVs , &
434  accoeff%n_Channels
435 
436  ! Trim the output based on the
437  ! dummy argument string length
438  info = long_string(1:min(len(info), len_trim(long_string)))
439 
440  END SUBROUTINE accoeff_info
441 
442 
443 !--------------------------------------------------------------------------------
444 !:sdoc+:
445 !
446 ! NAME:
447 ! ACCoeff_DefineVersion
448 !
449 ! PURPOSE:
450 ! Subroutine to return the module version information.
451 !
452 ! CALLING SEQUENCE:
453 ! CALL ACCoeff_DefineVersion( Id )
454 !
455 ! OUTPUTS:
456 ! Id: Character string containing the version Id information
457 ! for the module.
458 ! UNITS: N/A
459 ! TYPE: CHARACTER(*)
460 ! DIMENSION: Scalar
461 ! ATTRIBUTES: INTENT(OUT)
462 !
463 !:sdoc-:
464 !--------------------------------------------------------------------------------
465 
466  SUBROUTINE accoeff_defineversion( Id )
467  CHARACTER(*), INTENT(OUT) :: id
468  id = module_version_id
469  END SUBROUTINE accoeff_defineversion
470 
471 
472 !--------------------------------------------------------------------------------
473 !:sdoc+:
474 !
475 ! NAME:
476 ! ACCoeff_Subset
477 !
478 ! PURPOSE:
479 ! Subroutine to return a channel subset of the input ACCoeff object.
480 !
481 ! CALLING SEQUENCE:
482 ! CALL ACCoeff_Subset( ACCoeff, Subset, AC_Subset )
483 !
484 ! OBJECTS:
485 ! ACCoeff: ACCoeff object which is to be subsetted.
486 ! UNITS: N/A
487 ! TYPE: ACCoeff_type
488 ! DIMENSION: Scalar
489 ! ATTRIBUTES: INTENT(IN)
490 !
491 ! INPUTS:
492 ! Subset: Subset object containing the list of indices
493 ! corresponding the channels to be extracted.
494 ! UNITS: N/A
495 ! TYPE: Subset_type
496 ! DIMENSION: Scalar
497 ! ATTRIBUTES: INTENT(IN)
498 !
499 ! OUTPUTS:
500 ! AC_Subset: ACCoeff object containing the requested channel subset
501 ! of the input ACCoeff data.
502 ! UNITS: N/A
503 ! TYPE: ACCoeff_type
504 ! DIMENSION: Scalar
505 ! ATTRIBUTES: INTENT(OUT)
506 !
507 !:sdoc-:
508 !--------------------------------------------------------------------------------
509 
510  SUBROUTINE accoeff_subset( &
511  ACCoeff , & ! Input
512  Sensor_Channel, & ! Input
513  AC_Subset ) ! Output
514  ! Arguments
515  TYPE(accoeff_type), INTENT(IN) :: accoeff
516  INTEGER , INTENT(IN) :: sensor_channel(:)
517  TYPE(accoeff_type), INTENT(OUT) :: ac_subset
518  ! Local variables
519  TYPE(subset_type) :: subset
520  INTEGER :: n_subset_channels
521  INTEGER, ALLOCATABLE :: idx(:)
522 
523  ! Check input is valid
524  IF ( .NOT. accoeff_associated(accoeff) ) RETURN
525 
526 
527  ! Generate the subset list
528  CALL subset_generate( &
529  subset, &
530  accoeff%Sensor_Channel, &
531  sensor_channel )
532  IF ( .NOT. subset_associated( subset ) ) RETURN
533 
534 
535  ! Allocate the output subset ACCoeff object
536  CALL subset_getvalue( subset, n_values = n_subset_channels, index = idx )
537  CALL accoeff_create( ac_subset, accoeff%n_FOVs, n_subset_channels )
538  IF ( .NOT. accoeff_associated(ac_subset) ) RETURN
539 
540 
541  ! Extract out the subset channels
542  ! ...First assign some scalars
543  ac_subset%Version = accoeff%Version
544  ac_subset%Sensor_Id = accoeff%Sensor_Id
545  ac_subset%WMO_Satellite_ID = accoeff%WMO_Satellite_ID
546  ac_subset%WMO_Sensor_ID = accoeff%WMO_Sensor_ID
547  ! ...and now extract the subset
548  ac_subset%Sensor_Channel = accoeff%Sensor_Channel(idx)
549  ac_subset%A_earth = accoeff%A_earth(:,idx)
550  ac_subset%A_space = accoeff%A_space(:,idx)
551  ac_subset%A_platform = accoeff%A_platform(:,idx)
552 
553  END SUBROUTINE accoeff_subset
554 
555 
556 !--------------------------------------------------------------------------------
557 !:sdoc+:
558 !
559 ! NAME:
560 ! ACCoeff_Concat
561 !
562 ! PURPOSE:
563 ! Subroutine to concatenate multiple ACCoeff objects along the channel
564 ! dimension into a single ACCoeff object.
565 !
566 ! CALLING SEQUENCE:
567 ! CALL ACCoeff_Concat( ACCoeff, AC_Array, Sensor_Id=Sensor_Id )
568 !
569 ! OBJECTS:
570 ! ACCoeff: ACCoeff object containing the concatenated result.
571 ! UNITS: N/A
572 ! TYPE: ACCoeff_type
573 ! DIMENSION: Scalar
574 ! ATTRIBUTES: INTENT(OUT)
575 !
576 ! INPUTS:
577 ! AC_Array: Array of ACCoeff objects to be concatenated.
578 ! UNITS: N/A
579 ! TYPE: ACCoeff_type
580 ! DIMENSION: Rank-1
581 ! ATTRIBUTES: INTENT(IN)
582 !
583 ! OPTIONAL INPUTS:
584 ! Sensor_Id: Sensor id character to string to use for the concatenated
585 ! result. If not specified, the sensor id of the first valid
586 ! element of AC_Array is used.
587 ! UNITS: N/A
588 ! TYPE: CHARACTER(*)
589 ! DIMENSION: Scalar
590 ! ATTRIBUTES: INTENT(IN), OPTIONAL
591 !
592 !:sdoc-:
593 !--------------------------------------------------------------------------------
594 
595  SUBROUTINE accoeff_concat( &
596  ACCoeff , & ! Output
597  AC_Array , & ! Input
598  Sensor_Id ) ! Optional input
599  ! Arguments
600  TYPE(accoeff_type) , INTENT(OUT) :: accoeff
601  TYPE(accoeff_type) , INTENT(IN) :: ac_array(:)
602  CHARACTER(*), OPTIONAL, INTENT(IN) :: sensor_id
603  ! Local variables
604  INTEGER, ALLOCATABLE :: valid_index(:)
605  INTEGER :: i, j, n_ac, n_valid, n_channels
606  INTEGER :: ch1, ch2
607 
608  ! Set up
609  ! ...Check input is valid
610  n_ac = SIZE(ac_array)
611  IF ( n_ac < 1 ) RETURN
612  ! ...Count valid input
613  n_valid = count(accoeff_associated(ac_array))
614  IF ( n_valid == 0 ) RETURN
615  ! ...Index the valid input
616  ALLOCATE( valid_index(n_valid) )
617  valid_index = pack( (/(i,i=1,n_ac)/), mask=accoeff_associated(ac_array) )
618  ! ...Check non-channel dimensions and ids
619  DO j = 1, n_valid
620  i = valid_index(j)
621  IF ( ac_array(i)%n_FOVs /= ac_array(valid_index(1))%n_FOVs .OR. &
622  ac_array(i)%WMO_Satellite_ID /= ac_array(valid_index(1))%WMO_Satellite_ID .OR. &
623  ac_array(i)%WMO_Sensor_ID /= ac_array(valid_index(1))%WMO_Sensor_ID ) THEN
624  RETURN
625  END IF
626  END DO
627 
628 
629  ! Sum channel dimensions
630  n_channels = sum(ac_array(valid_index)%n_Channels)
631 
632 
633  ! Allocate the output concatenated ACCoeff object
634  CALL accoeff_create( &
635  accoeff, &
636  ac_array(valid_index(1))%n_FOVs, &
637  n_channels )
638  IF ( .NOT. accoeff_associated(accoeff) ) RETURN
639 
640 
641  ! Concatenate the channel data
642  ! ...First assign the non-channel dependent data
643  accoeff%Version = ac_array(valid_index(1))%Version
644  IF ( PRESENT(sensor_id) ) THEN
645  accoeff%Sensor_Id = adjustl(sensor_id)
646  ELSE
647  accoeff%Sensor_Id = ac_array(valid_index(1))%Sensor_Id
648  END IF
649  accoeff%WMO_Satellite_ID = ac_array(valid_index(1))%WMO_Satellite_ID
650  accoeff%WMO_Sensor_ID = ac_array(valid_index(1))%WMO_Sensor_ID
651  ! ...and now concatenate the channel data
652  ch1 = 1
653  DO j = 1, n_valid
654  i = valid_index(j)
655 
656  ch2 = ch1 + ac_array(i)%n_Channels - 1
657 
658  accoeff%Sensor_Channel(ch1:ch2) = ac_array(i)%Sensor_Channel
659  accoeff%A_earth(:,ch1:ch2) = ac_array(i)%A_earth
660  accoeff%A_space(:,ch1:ch2) = ac_array(i)%A_space
661  accoeff%A_platform(:,ch1:ch2) = ac_array(i)%A_platform
662 
663  ch1 = ch2 + 1
664  END DO
665 
666 
667  ! Cleanup
668  DEALLOCATE( valid_index )
669 
670  END SUBROUTINE accoeff_concat
671 
672 
673 !--------------------------------------------------------------------------------
674 !:sdoc+:
675 !
676 ! NAME:
677 ! ACCoeff_ChannelReindex
678 !
679 ! PURPOSE:
680 ! Subroutine to re-index an ACCoeff object for a different complete
681 ! channel set.
682 !
683 ! CALLING SEQUENCE:
684 ! CALL ACCoeff_ChannelReindex( ACCoeff, Sensor_Channels )
685 !
686 ! OBJECTS:
687 ! ACCoeff: ACCoeff object to have its channel information reindexed.
688 ! UNITS: N/A
689 ! TYPE: ACCoeff_type
690 ! DIMENSION: Scalar
691 ! ATTRIBUTES: INTENT(IN OUT)
692 !
693 ! INPUTS:
694 ! Sensor_Channel: Array of channel numbers for which the ACCoeff object
695 ! is to be re-indexed against.
696 ! UNITS: N/A
697 ! TYPE: INTEGER
698 ! DIMENSION: Rank-1
699 ! ATTRIBUTES: INTENT(IN)
700 !
701 !:sdoc-:
702 !--------------------------------------------------------------------------------
703 
704  SUBROUTINE accoeff_channelreindex( &
705  ACCoeff , & ! In/output
706  Sensor_Channel ) ! Input
707  ! Arguments
708  TYPE(accoeff_type), INTENT(IN OUT) :: accoeff
709  INTEGER , INTENT(IN) :: sensor_channel(:)
710  ! Local variables
711  TYPE(accoeff_type) :: ac_copy
712  INTEGER :: i, i_orig
713  INTEGER :: n_channels
714 
715  ! Setup
716  IF ( .NOT. accoeff_associated(accoeff) ) RETURN
717  n_channels = SIZE(sensor_channel)
718  IF ( n_channels < 1 ) RETURN
719 
720 
721  ! Copy the input structure
722  ac_copy = accoeff
723 
724 
725  ! Allocate the reindexed ACCoeff object
726  CALL accoeff_create( &
727  accoeff , &
728  ac_copy%n_FOVs, &
729  n_channels )
730  IF ( .NOT. accoeff_associated(accoeff) ) RETURN
731 
732 
733  ! Fill the new structure
734  ! ...Copy over the non-channel related information
735  accoeff%Version = ac_copy%Version
736  accoeff%Sensor_Id = ac_copy%Sensor_Id
737  accoeff%WMO_Satellite_ID = ac_copy%WMO_Satellite_ID
738  accoeff%WMO_Sensor_ID = ac_copy%WMO_Sensor_ID
739  ! ...Copy over the all-channel related information
740  accoeff%Sensor_Channel = sensor_channel
741 
742 
743  ! Perform the channel reindexing
744  i_orig = 1
745  DO i = 1, n_channels
746  IF ( accoeff%Sensor_Channel(i) == ac_copy%Sensor_Channel(i_orig) ) THEN
747  accoeff%A_earth(:,i) = ac_copy%A_earth(:,i_orig)
748  accoeff%A_space(:,i) = ac_copy%A_space(:,i_orig)
749  accoeff%A_platform(:,i) = ac_copy%A_platform(:,i_orig)
750  i_orig = i_orig + 1
751  END IF
752  END DO
753 
754 
755  ! Clean up
756  CALL accoeff_destroy(ac_copy)
757 
758  END SUBROUTINE accoeff_channelreindex
759 
760 
761 
762 !##################################################################################
763 !##################################################################################
764 !## ##
765 !## ## PRIVATE MODULE ROUTINES ## ##
766 !## ##
767 !##################################################################################
768 !##################################################################################
769 
770 !------------------------------------------------------------------------------
771 !
772 ! NAME:
773 ! ACCoeff_Equal
774 !
775 ! PURPOSE:
776 ! Elemental function to test the equality of two ACCoeff objects.
777 ! Used in OPERATOR(==) interface block.
778 !
779 ! CALLING SEQUENCE:
780 ! is_equal = ACCoeff_Equal( x, y )
781 !
782 ! or
783 !
784 ! IF ( x == y ) THEN
785 ! ...
786 ! END IF
787 !
788 ! OBJECTS:
789 ! x, y: Two ACCoeff objects to be compared.
790 ! UNITS: N/A
791 ! TYPE: ACCoeff_type
792 ! DIMENSION: Scalar or any rank
793 ! ATTRIBUTES: INTENT(IN)
794 !
795 ! FUNCTION RESULT:
796 ! is_equal: Logical value indicating whether the inputs are equal.
797 ! UNITS: N/A
798 ! TYPE: LOGICAL
799 ! DIMENSION: Same as inputs.
800 !
801 !------------------------------------------------------------------------------
802 
803  ELEMENTAL FUNCTION accoeff_equal( x, y ) RESULT( is_equal )
804  TYPE(accoeff_type), INTENT(IN) :: x, y
805  LOGICAL :: is_equal
806 
807  ! Set up
808  is_equal = .false.
809 
810  ! Check the object association status
811  IF ( (.NOT. accoeff_associated(x)) .OR. &
812  (.NOT. accoeff_associated(y)) ) RETURN
813 
814  ! Check contents
815  ! ...Release/version info
816  IF ( (x%Release /= y%Release) .OR. &
817  (x%Version /= y%Version) ) RETURN
818  ! ...Dimensions
819  IF ( (x%n_FOVs /= y%n_FOVs ) .OR. &
820  (x%n_Channels /= y%n_Channels ) ) RETURN
821  ! ...Scalars
822  IF ( (x%Sensor_Id /= y%Sensor_Id ) .OR. &
823  (x%WMO_Satellite_ID /= y%WMO_Satellite_ID) .OR. &
824  (x%WMO_Sensor_ID /= y%WMO_Sensor_ID ) ) RETURN
825  ! ...Arrays
826  IF ( all(x%Sensor_Channel == y%Sensor_Channel ) .AND. &
827  all(x%A_earth .equalto. y%A_earth ) .AND. &
828  all(x%A_space .equalto. y%A_space ) .AND. &
829  all(x%A_platform .equalto. y%A_platform ) ) &
830  is_equal = .true.
831 
832  END FUNCTION accoeff_equal
833 
834 END MODULE accoeff_define
integer, parameter, public failure
subroutine, public accoeff_inspect(ACCoeff)
elemental logical function accoeff_equal(x, y)
integer, parameter, public long
Definition: Type_Kinds.f90:76
subroutine, public accoeff_subset(ACCoeff, Sensor_Channel, AC_Subset)
integer, parameter ml
integer, parameter accoeff_release
integer, parameter sl
integer, parameter, public double
Definition: Type_Kinds.f90:106
subroutine, public accoeff_info(ACCoeff, Info)
elemental subroutine, public accoeff_destroy(ACCoeff)
integer, parameter accoeff_version
elemental logical function, public subset_associated(Subset)
real(double), parameter zero
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
subroutine, public accoeff_defineversion(Id)
integer, parameter, public invalid_wmo_satellite_id
subroutine, public accoeff_concat(ACCoeff, AC_Array, Sensor_Id)
logical function, public accoeff_validrelease(ACCoeff)
real(double), parameter one
subroutine, public subset_getvalue(Subset, n_Values, Number, Index)
integer, parameter, public invalid_wmo_sensor_id
elemental subroutine, public accoeff_create(ACCoeff, n_FOVs, n_Channels)
#define min(a, b)
Definition: mosaic_util.h:32
subroutine, public subset_generate(Subset, List, Subset_List)
character(*), parameter module_version_id
integer, parameter, public success
subroutine, public accoeff_channelreindex(ACCoeff, Sensor_Channel)
elemental logical function, public accoeff_associated(ACCoeff)
integer, parameter, public information