40 PUBLIC ::
OPERATOR(==)
61 INTERFACE OPERATOR(==)
63 END INTERFACE OPERATOR(==)
70 '$Id: SEcategory_Define.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $' 79 REAL(fp),
PARAMETER ::
zero = 0.0_fp
80 REAL(fp),
PARAMETER ::
one = 1.0_fp
82 INTEGER,
PARAMETER ::
ml = 256
83 INTEGER,
PARAMETER ::
sl = 80
92 LOGICAL :: is_allocated = .false.
99 CHARACTER(SL) :: classification_name =
'' 101 INTEGER(Long) :: string_length =
sl 102 INTEGER(Long) :: n_frequencies = 0
103 INTEGER(Long) :: n_surface_types = 0
105 REAL(Double),
ALLOCATABLE :: frequency(:)
106 CHARACTER(SL),
ALLOCATABLE :: surface_type(:)
108 LOGICAL,
ALLOCATABLE :: surface_type_isvalid(:)
110 REAL(Double),
ALLOCATABLE :: reflectance(:,:)
164 status = self%Is_Allocated
192 self%Is_Allocated = .false.
193 self%n_Frequencies = 0
194 self%n_Surface_Types = 0
241 n_Frequencies , & ! Input
245 INTEGER ,
INTENT(IN) :: n_frequencies
246 INTEGER ,
INTENT(IN) :: n_surface_types
248 INTEGER :: alloc_stat
251 IF ( n_frequencies < 1 .OR. &
252 n_surface_types < 1 )
RETURN 256 ALLOCATE( self%Surface_Type_IsValid( n_surface_types ), &
257 self%Frequency( n_frequencies ), &
258 self%Surface_Type( n_surface_types ), &
259 self%Reflectance( n_frequencies, n_surface_types ), &
261 IF ( alloc_stat /= 0 )
RETURN 266 self%n_Frequencies = n_frequencies
267 self%n_Surface_Types = n_surface_types
269 self%Surface_Type_IsValid = .true.
270 self%Frequency =
zero 271 self%Surface_Type =
'' 272 self%Reflectance =
zero 275 self%Is_Allocated = .true.
305 WRITE(*,
'(1x,"SEcategory OBJECT")')
307 WRITE(*,
'(3x,"Release.Version :",1x,i0,".",i0)') self%Release, self%Version
309 WRITE(*,
'(3x,"Classification_Name :",1x,a)') trim(self%Classification_Name)
311 WRITE(*,
'(3x,"n_Frequencies :",1x,i0)') self%n_Frequencies
312 WRITE(*,
'(3x,"n_Surface_Types :",1x,i0)') self%n_Surface_Types
315 WRITE(*,
'(3x,"Frequency :")')
316 WRITE(*,
'(5(1x,es13.6,:))') self%Frequency
317 WRITE(*,
'(3x,"Surface_Type - (IsValid) :")')
318 DO n = 1, self%n_Surface_Types
319 WRITE(*,
'(5x,a," - (",l1,")")') trim(self%Surface_Type(n)), self%Surface_Type_IsValid(n)
322 WRITE(*,
'(3x,"Reflectance :")')
323 DO n = 1, self%n_Surface_Types
324 WRITE(*,
'(5x,a)') self%Surface_Type(n)
325 WRITE(*,
'(5(1x,es13.6,:))') self%Reflectance(:,n)
366 CHARACTER(*),
PARAMETER :: routine_name =
'SEcategory_ValidRelease' 377 WRITE( msg,
'("An SEcategory data update is needed. ", & 378 &"SEcategory release is ",i0,". Valid release is ",i0,"." )' ) &
387 WRITE( msg,
'("An SEcategory software update is needed. ", & 388 &"SEcategory release is ",i0,". Valid release is ",i0,"." )' ) &
430 CHARACTER(*),
INTENT(OUT) :: info
432 INTEGER,
PARAMETER :: carriage_return = 13
433 INTEGER,
PARAMETER :: linefeed = 10
435 CHARACTER(2000) :: long_string
438 WRITE( long_string, &
439 '(a,1x,"SEcategory RELEASE.VERSION: ",i2,".",i2.2,a,3x, & 440 &"CLASSIFICATION: ",a,",",2x,& 441 &"N_FREQUENCIES=",i0,2x,& 442 &"N_SURFACE_TYPES=",i0 )' ) &
443 achar(carriage_return)//achar(linefeed), &
444 self%Release, self%Version, &
445 achar(carriage_return)//achar(linefeed), &
446 trim(self%Classification_Name), &
447 self%n_Frequencies, &
452 info = long_string(1:
min(len(info), len_trim(long_string)))
490 CHARACTER(LEN(self%Datatype_Name)) :: datatype_name
492 datatype_name = self%Datatype_Name
543 CHARACTER(*) ,
INTENT(IN) :: surface_type
554 DO i = 1, self%n_Surface_Types
555 IF ( self%Surface_Type(i) == surface_type )
THEN 588 CHARACTER(*),
INTENT(OUT) :: id
675 Version , & ! Optional input
676 Classification_Name , & ! Optional input
677 Frequency , & ! Optional input
678 Surface_Type , & ! Optional input
679 Surface_Type_IsValid, & ! Optional input
683 INTEGER ,
OPTIONAL,
INTENT(IN) :: version
684 CHARACTER(*),
OPTIONAL,
INTENT(IN) :: classification_name
685 REAL(fp) ,
OPTIONAL,
INTENT(IN) :: frequency(:)
686 CHARACTER(*),
OPTIONAL,
INTENT(IN) :: surface_type(:)
687 LOGICAL ,
OPTIONAL,
INTENT(IN) :: surface_type_isvalid(:)
688 REAL(fp) ,
OPTIONAL,
INTENT(IN) :: reflectance(:,:)
692 IF (
PRESENT(version) ) self%Version = version
693 IF (
PRESENT(classification_name) ) self%Classification_Name = classification_name
695 IF (
PRESENT(frequency) )
THEN 696 IF (
SIZE(frequency) == self%n_Frequencies )
THEN 697 self%Frequency = frequency
699 self%Frequency =
zero 703 IF (
PRESENT(surface_type) )
THEN 704 IF (
SIZE(surface_type) == self%n_Surface_Types )
THEN 705 self%Surface_Type = surface_type
707 self%Surface_Type =
'' 711 IF (
PRESENT(surface_type_isvalid) )
THEN 712 IF (
SIZE(surface_type_isvalid) == self%n_Surface_Types )
THEN 713 self%Surface_Type_IsValid = surface_type_isvalid
715 self%Surface_Type_IsValid = .false.
719 IF (
PRESENT(reflectance) )
THEN 720 IF (
SIZE(reflectance,dim=1) == self%n_Frequencies .AND. &
721 SIZE(reflectance,dim=2) == self%n_Surface_Types )
THEN 722 self%Reflectance = reflectance
724 self%Reflectance =
zero 842 Surface_Type_ToGet , & ! Optional input
843 Version , & ! Optional output
844 Classification_Name , & ! Optional output
845 n_Frequencies , & ! Optional output
846 n_Surface_Types , & ! Optional output
847 Frequency , & ! Optional output
848 Surface_Type , & ! Optional output
849 Surface_Type_IsValid, & ! Optional output
850 Reflectance , & ! Optional output
851 Surface_Reflectance )
854 CHARACTER(*),
OPTIONAL,
INTENT(IN) :: surface_type_toget
855 INTEGER ,
OPTIONAL,
INTENT(OUT) :: version
856 CHARACTER(*),
OPTIONAL,
INTENT(OUT) :: classification_name
857 INTEGER ,
OPTIONAL,
INTENT(OUT) :: n_frequencies
858 INTEGER ,
OPTIONAL,
INTENT(OUT) :: n_surface_types
859 REAL(fp) ,
ALLOCATABLE,
OPTIONAL,
INTENT(OUT) :: frequency(:)
860 CHARACTER(*),
ALLOCATABLE,
OPTIONAL,
INTENT(OUT) :: surface_type(:)
861 LOGICAL ,
ALLOCATABLE,
OPTIONAL,
INTENT(OUT) :: surface_type_isvalid(:)
862 REAL(fp) ,
ALLOCATABLE,
OPTIONAL,
INTENT(OUT) :: reflectance(:,:)
863 REAL(fp) ,
ALLOCATABLE,
OPTIONAL,
INTENT(OUT) :: surface_reflectance(:)
869 IF (
PRESENT(version ) ) version = self%Version
870 IF (
PRESENT(classification_name) ) classification_name = self%Classification_Name
871 IF (
PRESENT(n_frequencies ) ) n_frequencies = self%n_Frequencies
872 IF (
PRESENT(n_surface_types ) ) n_surface_types = self%n_Surface_Types
874 IF (
PRESENT(frequency) )
THEN 875 ALLOCATE(frequency(self%n_Frequencies))
876 frequency = self%Frequency
879 IF (
PRESENT(surface_type) )
THEN 880 ALLOCATE(surface_type(self%n_Surface_Types))
881 surface_type = self%Surface_Type
884 IF (
PRESENT(surface_type_isvalid) )
THEN 885 ALLOCATE(surface_type_isvalid(self%n_Surface_Types))
886 surface_type_isvalid = self%Surface_Type_IsValid
889 IF (
PRESENT(reflectance) )
THEN 890 ALLOCATE(reflectance(self%n_Frequencies, self%n_Surface_Types))
891 reflectance = self%Reflectance
894 IF (
PRESENT(surface_type_toget) .AND.
PRESENT(surface_reflectance) )
THEN 898 ALLOCATE(surface_reflectance(self%n_Frequencies))
899 surface_reflectance = self%Reflectance(:,i)
976 n_Frequencies , & ! Optional output
977 n_Surface_Types, & ! Optional output
978 Release , & ! Optional output
979 Version , & ! Optional output
980 Title , & ! Optional output
981 History , & ! Optional output
985 CHARACTER(*),
INTENT(IN) :: filename
986 INTEGER ,
OPTIONAL,
INTENT(OUT) :: n_frequencies
987 INTEGER ,
OPTIONAL,
INTENT(OUT) :: n_surface_types
988 INTEGER ,
OPTIONAL,
INTENT(OUT) :: release
989 INTEGER ,
OPTIONAL,
INTENT(OUT) :: version
990 CHARACTER(*),
OPTIONAL,
INTENT(OUT) :: title
991 CHARACTER(*),
OPTIONAL,
INTENT(OUT) :: history
992 CHARACTER(*),
OPTIONAL,
INTENT(OUT) :: comment
996 CHARACTER(*),
PARAMETER :: routine_name =
'SEcategory_InquireFile' 999 CHARACTER(ML) :: io_msg
1009 msg =
'File '//trim(filename)//
' not found.' 1016 IF ( err_stat /=
success )
THEN 1017 msg =
'Error opening '//trim(filename)
1024 IF ( err_stat /=
success )
THEN 1025 msg =
'Error reading Datatype_Name' 1035 READ( fid, iostat=io_stat, iomsg=io_msg ) &
1036 secategory%Release, &
1038 IF ( io_stat /= 0 )
THEN 1039 msg =
'Error reading Release/Version - '//trim(io_msg)
1043 msg =
'SEcategory Release check failed.' 1049 READ( fid, iostat=io_stat, iomsg=io_msg ) &
1050 secategory%n_Frequencies , &
1051 secategory%n_Surface_Types
1052 IF ( io_stat /= 0 )
THEN 1053 msg =
'Error reading dimension values from '//trim(filename)//
' - '//trim(io_msg)
1062 history = history, &
1064 IF ( err_stat /=
success )
THEN 1065 msg =
'Error reading global attributes' 1071 CLOSE( fid, iostat=io_stat, iomsg=io_msg )
1072 IF ( io_stat /= 0 )
THEN 1073 msg =
'Error closing '//trim(filename)//
' - '//trim(io_msg)
1079 IF (
PRESENT(n_frequencies ) ) n_frequencies = secategory%n_Frequencies
1080 IF (
PRESENT(n_surface_types) ) n_surface_types = secategory%n_Surface_Types
1081 IF (
PRESENT(release ) ) release = secategory%Release
1082 IF (
PRESENT(version ) ) version = secategory%Version
1089 CLOSE( fid, iostat=io_stat, iomsg=io_msg )
1090 IF ( io_stat /= 0 ) &
1091 msg = trim(msg)//
'; Error closing input file during error cleanup - '//trim(io_msg)
1167 SEcategory, & ! Output
1168 Filename , & ! Input
1169 No_Close , & ! Optional input
1170 Quiet , & ! Optional input
1171 Title , & ! Optional output
1172 History , & ! Optional output
1173 Comment , & ! Optional output
1178 CHARACTER(*),
INTENT(IN) :: filename
1179 LOGICAL,
OPTIONAL,
INTENT(IN) :: no_close
1180 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
1181 CHARACTER(*),
OPTIONAL,
INTENT(OUT) :: title
1182 CHARACTER(*),
OPTIONAL,
INTENT(OUT) :: history
1183 CHARACTER(*),
OPTIONAL,
INTENT(OUT) :: comment
1184 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
1188 CHARACTER(*),
PARAMETER :: routine_name =
'SEcategory_ReadFile' 1190 CHARACTER(ML) :: msg
1191 CHARACTER(ML) :: io_msg
1192 LOGICAL :: close_file
1202 IF (
PRESENT(no_close) ) close_file = .NOT. no_close
1205 IF (
PRESENT(quiet) ) noisy = .NOT. quiet
1207 IF (
PRESENT(debug) )
THEN 1208 IF ( debug ) noisy = .true.
1215 INQUIRE( file=filename, number=fid )
1218 msg =
'Error inquiring '//trim(filename)//
' for its FileID' 1225 IF ( err_stat /=
success )
THEN 1226 msg =
'Error opening '//trim(filename)
1230 msg =
'File '//trim(filename)//
' not found.' 1238 IF ( err_stat /=
success )
THEN 1239 msg =
'Error reading Datatype_Name' 1249 READ( fid, iostat=io_stat, iomsg=io_msg ) &
1252 IF ( io_stat /= 0 )
THEN 1253 msg =
'Error reading Release/Version - '//trim(io_msg)
1257 msg =
'SEcategory Release check failed.' 1263 READ( fid, iostat=io_stat, iomsg=io_msg ) &
1264 dummy%n_Frequencies , &
1265 dummy%n_Surface_Types
1266 IF ( io_stat /= 0 )
THEN 1267 msg =
'Error reading data dimensions - '//trim(io_msg)
1273 dummy%n_Frequencies , &
1274 dummy%n_Surface_Types )
1276 msg =
'SEcategory object allocation failed.' 1280 secategory%Version = dummy%Version
1287 history = history, &
1289 IF ( err_stat /=
success )
THEN 1290 msg =
'Error reading global attributes' 1296 READ( fid, iostat=io_stat, iomsg=io_msg ) &
1297 secategory%Classification_Name
1298 IF ( io_stat /= 0 )
THEN 1299 msg =
'Error reading classification name - '//trim(io_msg)
1306 READ( fid, iostat=io_stat, iomsg=io_msg ) &
1307 secategory%Surface_Type
1308 IF ( io_stat /= 0 )
THEN 1309 msg =
'Error reading surface type names - '//trim(io_msg)
1314 IF ( err_stat /=
success )
THEN 1315 msg =
'Error reading surface type validity array' 1319 READ( fid, iostat=io_stat, iomsg=io_msg ) &
1320 secategory%Frequency
1321 IF ( io_stat /= 0 )
THEN 1322 msg =
'Error reading dimensional vectors - '//trim(io_msg)
1326 READ( fid, iostat=io_stat, iomsg=io_msg ) &
1327 secategory%Reflectance
1328 IF ( io_stat /= 0 )
THEN 1329 msg =
'Error reading reflectance data - '//trim(io_msg)
1335 IF ( close_file )
THEN 1336 CLOSE( fid, iostat=io_stat, iomsg=io_msg )
1337 IF ( io_stat /= 0 )
THEN 1338 msg =
'Error closing '//trim(filename)//
' - '//trim(io_msg)
1354 CLOSE( fid, iostat=io_stat, iomsg=io_msg )
1355 IF ( io_stat /= 0 ) &
1356 msg = trim(msg)//
'; Error closing input file during error cleanup - '//trim(io_msg)
1432 SEcategory, & ! Input
1433 Filename , & ! Input
1434 No_Close , & ! Optional input
1435 Quiet , & ! Optional input
1436 Title , & ! Optional input
1437 History , & ! Optional input
1438 Comment , & ! Optional input
1443 CHARACTER(*),
INTENT(IN) :: filename
1444 LOGICAL,
OPTIONAL,
INTENT(IN) :: no_close
1445 LOGICAL,
OPTIONAL,
INTENT(IN) :: quiet
1446 CHARACTER(*),
OPTIONAL,
INTENT(IN) :: title
1447 CHARACTER(*),
OPTIONAL,
INTENT(IN) :: history
1448 CHARACTER(*),
OPTIONAL,
INTENT(IN) :: comment
1449 LOGICAL,
OPTIONAL,
INTENT(IN) :: debug
1453 CHARACTER(*),
PARAMETER :: routine_name =
'SEcategory_WriteFile' 1455 CHARACTER(ML) :: msg
1456 CHARACTER(ML) :: io_msg
1457 LOGICAL :: close_file
1467 IF (
PRESENT(no_close) ) close_file = .NOT. no_close
1470 IF (
PRESENT(quiet) ) noisy = .NOT. quiet
1472 IF (
PRESENT(debug) )
THEN 1473 IF ( debug ) noisy = .true.
1477 msg =
'SEcategory object is empty.' 1485 INQUIRE( file=filename, number=fid )
1488 msg =
'Error inquiring '//trim(filename)//
' for its FileID' 1494 IF ( err_stat /=
success )
THEN 1495 msg =
'Error opening '//trim(filename)
1502 WRITE( fid, iostat=io_stat, iomsg=io_msg ) &
1503 len(secategory%Datatype_Name)
1504 IF ( io_stat /= 0 )
THEN 1505 msg =
'Error writing Datatype_Name length - '//trim(io_msg)
1508 WRITE( fid, iostat=io_stat, iomsg=io_msg ) &
1509 secategory%Datatype_Name
1510 IF ( io_stat /= 0 )
THEN 1511 msg =
'Error writing Datatype_Name - '//trim(io_msg)
1517 WRITE( fid, iostat=io_stat, iomsg=io_msg ) &
1518 secategory%Release, &
1520 IF ( io_stat /= 0 )
THEN 1521 msg =
'Error writing Release/Version - '//trim(io_msg)
1527 WRITE( fid, iostat=io_stat, iomsg=io_msg ) &
1528 secategory%n_Frequencies , &
1529 secategory%n_Surface_Types
1530 IF ( io_stat /= 0 )
THEN 1531 msg =
'Error writing data dimensions - '//trim(io_msg)
1541 history = history, &
1543 IF ( err_stat /=
success )
THEN 1544 msg =
'Error writing global attributes' 1550 WRITE( fid, iostat=io_stat, iomsg=io_msg ) &
1551 secategory%Classification_Name
1552 IF ( io_stat /= 0 )
THEN 1553 msg =
'Error writing classification name - '//trim(io_msg)
1560 WRITE( fid, iostat=io_stat, iomsg=io_msg ) &
1561 secategory%Surface_Type
1562 IF ( io_stat /= 0 )
THEN 1563 msg =
'Error writing surface type names - '//trim(io_msg)
1568 IF ( err_stat /=
success )
THEN 1569 msg =
'Error writing surface type validity array' 1573 WRITE( fid, iostat=io_stat, iomsg=io_msg ) &
1574 secategory%Frequency
1575 IF ( io_stat /= 0 )
THEN 1576 msg =
'Error writing dimensional vectors - '//trim(io_msg)
1580 WRITE( fid, iostat=io_stat, iomsg=io_msg ) &
1581 secategory%Reflectance
1582 IF ( io_stat /= 0 )
THEN 1583 msg =
'Error writing reflectance data - '//trim(io_msg)
1589 IF ( close_file )
THEN 1590 CLOSE( fid, iostat=io_stat, iomsg=io_msg )
1591 IF ( io_stat /= 0 )
THEN 1592 msg =
'Error closing '//trim(filename)//
' - '//trim(io_msg)
1608 CLOSE( fid, iostat=io_stat, iomsg=io_msg )
1609 IF ( io_stat /= 0 ) &
1610 msg = trim(msg)//
'; Error closing output file during error cleanup - '//trim(io_msg)
1673 IF ( (x%Release /= y%Release) .OR. &
1674 (x%Version /= y%Version) )
RETURN 1676 IF ( (x%Classification_Name /= y%Classification_Name) )
RETURN 1678 IF ( (x%n_Frequencies /= y%n_Frequencies ) .OR. &
1679 (x%n_Surface_Types /= y%n_Surface_Types ) )
RETURN 1681 IF ( all(x%Frequency .equalto. y%Frequency ) .AND. &
1682 all(x%Surface_Type == y%Surface_Type ) .AND. &
1683 all(x%Reflectance .equalto. y%Reflectance ) ) &
1691 FUNCTION read_datatype( fid, datatype_name )
RESULT( err_stat )
1693 INTEGER ,
INTENT(IN) :: fid
1694 CHARACTER(*),
INTENT(OUT) :: datatype_name
1698 CHARACTER(1),
ALLOCATABLE :: dummy(:)
1701 INTEGER :: alloc_stat
1708 READ( fid, iostat=io_stat )
strlen 1709 IF ( io_stat /= 0 )
RETURN 1712 ALLOCATE( dummy(
strlen), stat=alloc_stat )
1713 IF ( alloc_stat /= 0 )
RETURN 1716 READ( fid, iostat=io_stat ) dummy
1717 IF ( io_stat /= 0 )
RETURN 1720 DO i = 1,
min(
strlen,len(datatype_name))
1721 datatype_name(i:i) = dummy(i)
integer function read_datatype(fid, datatype_name)
integer, parameter, public failure
subroutine, public secategory_info(self, Info)
integer, parameter, public strlen
real(fp), parameter, public zero
integer, parameter, public long
integer function, public secategory_writefile(SEcategory, Filename, No_Close, Quiet, Title, History, Comment, Debug)
integer function, public secategory_readfile(SEcategory, Filename, No_Close, Quiet, Title, History, Comment, Debug)
integer, parameter, public fp
pure character(len(self%datatype_name)) function, public secategory_name(self)
integer function, public readgatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
integer, parameter, public double
elemental logical function, public secategory_associated(self)
elemental logical function secategory_equal(x, y)
subroutine inquire_cleanup()
logical function, public secategory_validrelease(self)
subroutine read_cleanup()
subroutine write_cleanup()
integer, parameter secategory_version
integer function, public open_binary_file(Filename, FileID, For_Output, No_Check)
real(fp), parameter, public one
recursive subroutine, public display_message(Routine_Name, Message, Error_State, Message_Log)
pure integer function, public secategory_index(self, Surface_Type)
subroutine, public secategory_defineversion(Id)
elemental subroutine, public secategory_destroy(self)
subroutine, public secategory_inspect(self)
integer, parameter secategory_release
character(*), parameter, public secategory_datatype
integer function, public secategory_inquirefile(Filename, n_Frequencies, n_Surface_Types, Release, Version, Title, History, Comment)
integer function, public writegatts_binary_file(fid, Write_Module, Created_On, Title, History, Comment)
subroutine, public secategory_setvalue(self, Version, Classification_Name, Frequency, Surface_Type, Surface_Type_IsValid, Reflectance)
character(*), parameter write_error_status
character(*), parameter module_version_id
subroutine, public secategory_getvalue(self, Surface_Type_ToGet, Version, Classification_Name, n_Frequencies, n_Surface_Types, Frequency, Surface_Type, Surface_Type_IsValid, Reflectance, Surface_Reflectance)
integer, parameter, public success
elemental subroutine, public secategory_create(self, n_Frequencies, n_Surface_Types)
integer, parameter, public information