From 90c1d00a46a0a84dda208bef8642c9c9c0b56d50 Mon Sep 17 00:00:00 2001 From: Ryan McCarthy Date: Tue, 7 Jan 2025 17:01:32 -0700 Subject: [PATCH 1/2] adding subroutines to parse envi hdr headers and replacing xml parsing with hdr parsing for READ_BSQ_RASTER --- build/source/elmfire_io.f90 | 388 +++++++++++++++++++++++++----------- 1 file changed, 267 insertions(+), 121 deletions(-) diff --git a/build/source/elmfire_io.f90 b/build/source/elmfire_io.f90 index b67209a..242d83f 100644 --- a/build/source/elmfire_io.f90 +++ b/build/source/elmfire_io.f90 @@ -1063,6 +1063,9 @@ SUBROUTINE READ_BSQ_HEADER_EXISTING_TILED(RASTER,FNIN) CLOSE(LUINPUT,IOSTAT=IOS) +RASTER%XLLCORNER = RASTER%ULXMAP - 0.5 * RASTER%CELLSIZE +RASTER%YLLCORNER = RASTER%ULYMAP + 0.5 * RASTER%CELLSIZE - REAL(RASTER%NROWS) * RASTER%CELLSIZE + RASTER%NCOLS = RASTER%NCOLS * 3 RASTER%NROWS = RASTER%NROWS * 3 RASTER%BANDROWBYTES = (RASTER%NBITS/8) * RASTER%NCOLS @@ -1093,6 +1096,15 @@ SUBROUTINE READ_BSQ_RASTER(RASTER,INDIR,FN) INTEGER*2, ALLOCATABLE, DIMENSION(:) :: I2VALUES INTEGER*2, ALLOCATABLE, DIMENSION(:,:) :: I2TEMP +! Parsed ENVI HDR variables +INTEGER :: SAMPLES, LINES, BANDS, DATA_TYPE, HEADER_OFFSET, BYTE_ORDER +REAL :: DATA_IGNORE_VALUE, X_PIXEL_REFERENCE, Y_PIXEL_REFERENCE +REAL :: EASTING, NORTHING, X_PIXEL_SIZE, Y_PIXEL_SIZE +CHARACTER(3) :: INTERLEAVE +CHARACTER(1024) :: COORDINATE_SYSTEM, DESCRIPTION +CHARACTER(1024) :: DEFAULT_BANDS, BAND_NAMES +CHARACTER(64) :: FILE_TYPE, PROJECTION_NAME + IF (VRT_INSTEAD_OF_TIF) THEN FNTIF = TRIM(INDIR) // TRIM(FN) // '.vrt' ELSE @@ -1119,115 +1131,34 @@ SUBROUTINE READ_BSQ_RASTER(RASTER,INDIR,FN) WRITE(*,100) TRIM(SHELLSTR); CALL EXECUTE_COMMAND_LINE(TRIM(SHELLSTR)) ENDIF -! Open and parse BSQ XML: -OPEN(LUINPUT,FILE=TRIM(FNXML),FORM='FORMATTED',STATUS='OLD',IOSTAT=IOS) -IF (IOS .GT. 0) THEN - WRITE(*,*) 'Problem opening bsq xml header ', TRIM(FNXML) - WRITE(*,*) 'IOS: ', IOS - STOP -ENDIF - -! Trash first five lines -DO I = 1, 5 - READ(LUINPUT,100,IOSTAT=IOS) TEMPSTR - CONTINUE -ENDDO - -! Read number of bands: -READ(LUINPUT,100,IOSTAT=IOS) TEMPSTR -READ(TEMPSTR(22:30),*) TEMPSTR -TEMPSTR=TEMPSTR(1:LEN_TRIM(TEMPSTR)-1) -READ(TEMPSTR,*,IOSTAT=IOS) RASTER%NBANDS - -IF (IOS .NE. 0) THEN - RASTER%NBANDS=1 -ENDIF - -! Skip over byte order: -READ(LUINPUT,100,IOSTAT=IOS) - -! Read data type -READ(LUINPUT,100,IOSTAT=IOS) TEMPSTR -READ(TEMPSTR(26:26),*) TEMPSTR -READ(TEMPSTR,*) ITYPE -IF (ITYPE .EQ. 2) THEN - RASTER%PIXELTYPE='SIGNEDINT' - RASTER%NBITS=16 -ENDIF -IF (ITYPE .EQ. 4) THEN - RASTER%PIXELTYPE='FLOAT' - RASTER%NBITS=32 -ENDIF - -! Skip 3 more lines -DO I = 1, 3 - READ(LUINPUT,100,IOSTAT=IOS) -ENDDO - -! Read number of rows: -READ(LUINPUT,100,IOSTAT=IOS) TEMPSTR -READ(TEMPSTR(22:30),*) TEMPSTR -TEMPSTR=TEMPSTR(1:LEN_TRIM(TEMPSTR)-1) -READ(TEMPSTR,*) RASTER%NROWS - -! Read number of columns: -READ(LUINPUT,100,IOSTAT=IOS) TEMPSTR -READ(TEMPSTR(24:32),*) TEMPSTR -TEMPSTR=TEMPSTR(1:LEN_TRIM(TEMPSTR)-1) -READ(TEMPSTR,*) RASTER%NCOLS - -! Set BANDROWBYTES and TOTALROWBYTES: -RASTER%BANDROWBYTES = (RASTER%NBITS/8) * RASTER%NCOLS -RASTER%TOTALROWBYTES = RASTER%BANDROWBYTES * RASTER%NBANDS - -! Skip 5 or 6 more lines -DO I = 1, 5 - READ(LUINPUT,100,IOSTAT=IOS) TEMPSTR -ENDDO - -IF (LEN_TRIM(TEMPSTR) .LT. 15) THEN !This checks to see if we need to trash one more line - READ(LUINPUT,100,IOSTAT=IOS) TEMPSTR -ENDIF - -! Read nodata: -READ(LUINPUT,100,IOSTAT=IOS) TEMPSTR -READ(TEMPSTR(18:41),*) TEMPSTR -TEMPSTR=TEMPSTR(1:LEN_TRIM(TEMPSTR)-1) -READ(TEMPSTR,*) RASTER%NODATA_VALUE +CALL PARSE_ENVI_HEADER(FNHDR, DESCRIPTION, SAMPLES, LINES, BANDS, HEADER_OFFSET, FILE_TYPE, DATA_TYPE, INTERLEAVE, BYTE_ORDER, BAND_NAMES, COORDINATE_SYSTEM, DATA_IGNORE_VALUE, DEFAULT_BANDS, PROJECTION_NAME, X_PIXEL_REFERENCE, Y_PIXEL_REFERENCE, EASTING, NORTHING, X_PIXEL_SIZE, Y_PIXEL_SIZE) -! Close .xml file: -CLOSE(LUINPUT) - -! Open and parse BSQ header: -OPEN(LUINPUT,FILE=TRIM(FNHDR),FORM='FORMATTED',STATUS='OLD',IOSTAT=IOS) -IF (IOS .GT. 0) THEN - WRITE(*,*) 'Problem opening bsq header ', TRIM(FNHDR) -ENDIF +! These values should always be set +RASTER%NROWS = LINES +RASTER%NCOLS = SAMPLES +RASTER%NODATA_VALUE = DATA_IGNORE_VALUE +RASTER%XDIM = X_PIXEL_SIZE +RASTER%YDIM = Y_PIXEL_SIZE +RASTER%XLLCORNER = EASTING +RASTER%YLLCORNER = NORTHING - Y_PIXEL_SIZE * LINES +RASTER%LAYOUT = INTERLEAVE -IF (DEBUG_LEVEL .GT. 100) WRITE(*,*) 'Reading bsq header' +SELECT CASE(TRIM(INTERLEAVE)) + CASE('BIL') + RASTER%BYTEORDER = 'I' + CASE('BSQ') + RASTER%BYTEORDER = '0' +END SELECT -! Skip 11 lines -DO I = 1, 11 - READ(LUINPUT,100,IOSTAT=IOS) -ENDDO -! Read easting, northing, and cell size info: -READ(LUINPUT,100,IOSTAT=IOS) TEMPSTR -FOUND=.FALSE.; I=1 -DO WHILE (.NOT. FOUND) - IF(TEMPSTR(I:I) .EQ. ',') THEN - FOUND=.TRUE. - ELSE - I=I+1 - ENDIF -ENDDO -J=I+1 -DO I=1,100 - IF (TEMPSTR(I:I) .EQ. '}') TEMPSTR(I:I)=' ' -ENDDO -READ(TEMPSTR(J:),*) IDUMMY, IDUMMY, RASTER%XLLCORNER, RASTER%YLLCORNER, RASTER%XDIM, RASTER%YDIM -RASTER%YLLCORNER = RASTER%YLLCORNER - RASTER%YDIM * RASTER%NROWS -CLOSE(LUINPUT) +SELECT CASE(DATA_TYPE) + CASE(2) + RASTER%PIXELTYPE='SIGNEDINT' + RASTER%NBITS=16 + CASE(4) + RASTER%PIXELTYPE='FLOAT' + RASTER%NBITS=32 +END SELECT ! Check to make sure x and y cell sizes are the same: IF (RASTER%XDIM .NE. RASTER%YDIM) THEN @@ -1237,18 +1168,21 @@ SUBROUTINE READ_BSQ_RASTER(RASTER,INDIR,FN) RASTER%CELLSIZE=RASTER%XDIM ENDIF +! Need to handle some defaults +IF (BANDS .LT. 0) THEN + RASTER%NBANDS = 1 +ELSE + RASTER%NBANDS = BANDS +ENDIF + +! Set BANDROWBYTES and TOTALROWBYTES: +RASTER%BANDROWBYTES = (RASTER%NBITS/8) * RASTER%NCOLS +RASTER%TOTALROWBYTES = RASTER%BANDROWBYTES * RASTER%NBANDS + ! Set ULXMAP and ULYMAP RASTER%ULXMAP = RASTER%XLLCORNER + 0.5 * RASTER%CELLSIZE RASTER%ULYMAP = RASTER%YLLCORNER + RASTER%NROWS * RASTER%CELLSIZE - 0.5 * RASTER%CELLSIZE -! Set BYTEORDER and LAYOUT -RASTER%BYTEORDER = '0' -RASTER%LAYOUT = 'BSQ' - -! This is for bil: -RASTER%BYTEORDER = 'I' -RASTER%LAYOUT = 'BIL' - SELECT CASE(TRIM(RASTER%PIXELTYPE)) CASE('FLOAT') @@ -1524,7 +1458,7 @@ SUBROUTINE READ_BSQ_RASTER_EXISTING_TILED(RASTER,FNIN) IROW_SMALL = RASTER%NROWS DO IROW_BIG = IROW_BIG_LO, IROW_BIG_HI - RASTER%R4(ICOL_BIG_LO:ICOL_BIG_HI,IROW_BIG,MIN(IBAND,WS%NBANDS)) = RTEMP(:,IROW_SMALL) + RASTER%R4(ICOL_BIG_LO:ICOL_BIG_HI,IROW_BIG,IBAND) = RTEMP(:,IROW_SMALL) IROW_SMALL = IROW_SMALL - 1 ENDDO ENDDO @@ -1996,7 +1930,7 @@ SUBROUTINE POSTPROCESS CHARACTER(81) :: PREFIX CHARACTER(88) :: FIRE_ID CHARACTER(400) :: FN, HEADER -TYPE(RASTER_TYPE) :: INTERMEDIATE_R4!, INTERMEDIATE_I2 +TYPE(RASTER_TYPE) :: INTERMEDIATE_I2, INTERMEDIATE_R4 TYPE(RASTER_TYPE), POINTER :: R IF (IRANK_WORLD .EQ. 0 .AND. DUMP_FIRE_SIZE_STATS) THEN @@ -2171,17 +2105,16 @@ SUBROUTINE POSTPROCESS CALL MPI_BARRIER(MPI_COMM_WORLD, IERR) -! Currently not working with ACCUMULATE_EMBER_FLUX = .TRUE. +! This block need modification, datatype of EMBER_FLUX changed to float, and EMBER_FLUX%R4 is a NCOLS by NROWS by NBANDS 3-D tuple IF (DUMP_EMBER_FLUX .AND. ACCUMULATE_EMBER_FLUX) THEN R=>TIMES_BURNED + CALL ALLOCATE_EMPTY_RASTER(INTERMEDIATE_I2, R%NCOLS, R%NROWS, 1, R%XLLCORNER, R%YLLCORNER, R%CELLSIZE, 0., 'SIGNEDINT ') - CALL ALLOCATE_EMPTY_RASTER(INTERMEDIATE_R4, R%NCOLS, R%NROWS, EMBER_FLUX%NBANDS, R%XLLCORNER, R%YLLCORNER, R%CELLSIZE, 0., 'FLOAT ') - - CALL MPI_REDUCE(EMBER_FLUX%R4(:,:,:), INTERMEDIATE_R4%R4(:,:,:), ANALYSIS_NCOLS*ANALYSIS_NROWS*EMBER_FLUX%NBANDS, & - MPI_REAL, MPI_SUM, 0, MPI_COMM_WORLD, IERR) + CALL MPI_REDUCE(EMBER_FLUX%I2(:,:,1), INTERMEDIATE_I2%I2(:,:,1), ANALYSIS_NCOLS*ANALYSIS_NROWS, & + MPI_SHORT, MPI_SUM, 0, MPI_COMM_WORLD, IERR) IF (IRANK_WORLD .EQ. 0) THEN FN='ember_flux' - CALL WRITE_BIL_RASTER(INTERMEDIATE_R4, OUTPUTS_DIRECTORY, FN, CONVERT_TO_GEOTIFF, .TRUE., IRANK_WORLD) + CALL WRITE_BIL_RASTER(INTERMEDIATE_I2, OUTPUTS_DIRECTORY, FN, CONVERT_TO_GEOTIFF, .TRUE., IRANK_WORLD) ENDIF ENDIF @@ -2218,6 +2151,219 @@ SUBROUTINE WRITE_NODE(C,IRANK,ICASE,T) END SUBROUTINE WRITE_NODE ! ***************************************************************************** +! ***************************************************************************** +SUBROUTINE PARSE_ENVI_HEADER(HDR_FILE_NAME, DESCRIPTION, SAMPLES, LINES, BANDS, HEADER_OFFSET, FILE_TYPE, DATA_TYPE, INTERLEAVE, BYTE_ORDER, BAND_NAMES, COORDINATE_SYSTEM, DATA_IGNORE_VALUE, DEFAULT_BANDS, PROJECTION_NAME, X_PIXEL_REFERENCE, Y_PIXEL_REFERENCE, EASTING, NORTHING, X_PIXEL_SIZE, Y_PIXEL_SIZE) +! ***************************************************************************** + IMPLICIT NONE + CHARACTER(LEN=*), INTENT(IN) :: HDR_FILE_NAME + INTEGER, INTENT(OUT) :: SAMPLES, LINES, BANDS, DATA_TYPE + INTEGER, INTENT(OUT) :: HEADER_OFFSET, BYTE_ORDER + REAL, INTENT(OUT) :: DATA_IGNORE_VALUE + CHARACTER(LEN=3), INTENT(OUT) :: INTERLEAVE + CHARACTER(LEN=1024), INTENT(OUT) :: COORDINATE_SYSTEM, DESCRIPTION + CHARACTER(LEN=1024), INTENT(OUT) :: DEFAULT_BANDS, BAND_NAMES + CHARACTER(LEN=64), INTENT(OUT) :: FILE_TYPE + ! Map Info Parameters + CHARACTER(64), INTENT(OUT) :: PROJECTION_NAME + REAL, INTENT(OUT) :: X_PIXEL_REFERENCE + REAL, INTENT(OUT) :: Y_PIXEL_REFERENCE + REAL, INTENT(OUT) :: EASTING + REAL, INTENT(OUT) :: NORTHING + REAL, INTENT(OUT) :: X_PIXEL_SIZE + REAL, INTENT(OUT) :: Y_PIXEL_SIZE + + CHARACTER(LEN=256), DIMENSION(7) :: MAP_INFO_PARAMS + CHARACTER(LEN=1024) :: LINE, CURRENT_KEY, CURRENT_VALUE + INTEGER :: IUNIT, IOS + LOGICAL :: READING_MULTILINE_VALUE, FOUND_SAMPLES, FOUND_LINES, FOUND_BANDS + LOGICAL :: FOUND_DATA_TYPE, FOUND_BYTE_ORDER, FOUND_DATA_IGNORE_VALUE + LOGICAL :: FOUND_MAP_INFO, FOUND_COORDINATE_SYSTEM, FOUND_DESCRIPTION + LOGICAL :: FOUND_FILE_TYPE, FOUND_DEFAULT_BANDS, FOUND_INTERLEAVE + LOGICAL :: FOUND_HEADER_OFFSET, FOUND_BAND_NAMES + + ! INITIALIZE FLAGS AND DEFAULT VALUES + READING_MULTILINE_VALUE = .FALSE. + FOUND_DESCRIPTION = .FALSE. + FOUND_SAMPLES = .FALSE. + FOUND_LINES = .FALSE. + FOUND_BANDS = .FALSE. + FOUND_HEADER_OFFSET = .FALSE. + FOUND_FILE_TYPE = .FALSE. + FOUND_DATA_TYPE = .FALSE. + FOUND_INTERLEAVE = .FALSE. + FOUND_BYTE_ORDER = .FALSE. + FOUND_MAP_INFO = .FALSE. + FOUND_COORDINATE_SYSTEM = .FALSE. + FOUND_BAND_NAMES = .FALSE. + FOUND_DATA_IGNORE_VALUE = .FALSE. + FOUND_DEFAULT_BANDS = .FALSE. + + ! OPEN THE FILE + OPEN(UNIT=10, FILE=HDR_FILE_NAME, STATUS='OLD', ACTION='READ', IOSTAT=IOS) + IF (IOS /= 0) THEN + PRINT *, 'ERROR OPENING HDR FILE: ', HDR_FILE_NAME + RETURN + ENDIF + + ! LOOP THROUGH EACH LINE IN THE FILE + DO + READ(10, '(A)', IOSTAT=IOS) LINE + IF (IOS /= 0) EXIT + + IF (READING_MULTILINE_VALUE) THEN + ! CONTINUE READING UNTIL THE MULTILINE VALUE ENDS + IF (INDEX(LINE, '}') > 0) THEN + CURRENT_VALUE = TRIM(CURRENT_VALUE) // ' ' // TRIM(ADJUSTL(LINE)) + READING_MULTILINE_VALUE = .FALSE. + ELSE + CURRENT_VALUE = TRIM(CURRENT_VALUE) // ' ' // TRIM(ADJUSTL(LINE)) + CYCLE + ENDIF + ELSE + CALL SPLIT_LINE(LINE, CURRENT_KEY, CURRENT_VALUE) + IF (INDEX(CURRENT_VALUE, '{') > 0 .AND. INDEX(CURRENT_VALUE, '}') == 0) THEN + READING_MULTILINE_VALUE = .TRUE. + CYCLE + ENDIF + ENDIF + + ! MATCH KEY TO EXPECTED VARIABLES AND STORE VALUES + SELECT CASE (TRIM(ADJUSTL(CURRENT_KEY))) + CASE ('description') + DESCRIPTION = TRIM(ADJUSTL(CURRENT_VALUE)); FOUND_DESCRIPTION = .TRUE. + CASE ('samples') + READ(CURRENT_VALUE, *) SAMPLES; FOUND_SAMPLES = .TRUE. + CASE ('lines') + READ(CURRENT_VALUE, *) LINES; FOUND_LINES = .TRUE. + CASE ('bands') + READ(CURRENT_VALUE, *) BANDS; FOUND_BANDS = .TRUE. + CASE ('header offset') + READ(CURRENT_VALUE, *) HEADER_OFFSET; FOUND_HEADER_OFFSET = .TRUE. + CASE ('file type') + FILE_TYPE = TRIM(ADJUSTL(CURRENT_VALUE)); FOUND_FILE_TYPE = .TRUE. + CASE ('data type') + READ(CURRENT_VALUE, *) DATA_TYPE; FOUND_DATA_TYPE = .TRUE. + CASE ('interleave') + INTERLEAVE = TRIM(ADJUSTL(CURRENT_VALUE)); FOUND_INTERLEAVE = .TRUE. + CASE ('byte order') + READ(CURRENT_VALUE, *) BYTE_ORDER; FOUND_BYTE_ORDER = .TRUE. + CASE ('map info') + CALL PARSE_MAP_INFO(TRIM(CURRENT_VALUE), MAP_INFO_PARAMS) + FOUND_MAP_INFO = .TRUE. + READ(MAP_INFO_PARAMS(1), *) PROJECTION_NAME + READ(MAP_INFO_PARAMS(2), *) X_PIXEL_REFERENCE + READ(MAP_INFO_PARAMS(3), *) Y_PIXEL_REFERENCE + READ(MAP_INFO_PARAMS(4), *) EASTING + READ(MAP_INFO_PARAMS(5), *) NORTHING + READ(MAP_INFO_PARAMS(6), *) X_PIXEL_SIZE + READ(MAP_INFO_PARAMS(7), *) Y_PIXEL_SIZE + CASE ('coordinate system string') + COORDINATE_SYSTEM = TRIM(ADJUSTL(CURRENT_VALUE)); FOUND_COORDINATE_SYSTEM = .TRUE. + CASE ('band names') + BAND_NAMES = TRIM(ADJUSTL(CURRENT_VALUE)); FOUND_BAND_NAMES = .TRUE. + CASE ('data ignore value') + READ(CURRENT_VALUE, *) DATA_IGNORE_VALUE; FOUND_DATA_IGNORE_VALUE = .TRUE. + CASE ('default bands') + DEFAULT_BANDS = TRIM(ADJUSTL(CURRENT_VALUE)); FOUND_DEFAULT_BANDS = .TRUE. + END SELECT + END DO + + ! CLOSE THE FILE + CLOSE(10) + + ! SET DEFAULT VALUES FOR MISSING VARIABLES + IF (.NOT. FOUND_DESCRIPTION) DESCRIPTION = 'UNKNOWN' + IF (.NOT. FOUND_SAMPLES) SAMPLES = -1 + IF (.NOT. FOUND_LINES) LINES = -1 + IF (.NOT. FOUND_BANDS) BANDS = 1 + IF (.NOT. FOUND_HEADER_OFFSET) HEADER_OFFSET = 0 + IF (.NOT. FOUND_FILE_TYPE) FILE_TYPE = 'UNKNOWN' + IF (.NOT. FOUND_DATA_TYPE) DATA_TYPE = -1 + IF (.NOT. FOUND_INTERLEAVE) INTERLEAVE = 'UNKNOWN' + IF (.NOT. FOUND_BYTE_ORDER) BYTE_ORDER = -1 + IF (.NOT. FOUND_MAP_INFO) THEN + PROJECTION_NAME = "UNKNOWN" + X_PIXEL_REFERENCE = 1 + Y_PIXEL_REFERENCE = 1 + EASTING = 0 + NORTHING = 0 + X_PIXEL_SIZE = 0 + Y_PIXEL_SIZE = 0 + ENDIF + IF (.NOT. FOUND_COORDINATE_SYSTEM) COORDINATE_SYSTEM = 'UNKNOWN' + IF (.NOT. FOUND_BAND_NAMES) BAND_NAMES = 'UNKNOWN' + IF (.NOT. FOUND_DATA_IGNORE_VALUE) DATA_IGNORE_VALUE = -9999.0 + IF (.NOT. FOUND_DEFAULT_BANDS) DEFAULT_BANDS = 'UNKNOWN' + +! ***************************************************************************** +END SUBROUTINE PARSE_ENVI_HEADER +! ***************************************************************************** + +! ***************************************************************************** +SUBROUTINE SPLIT_LINE(LINE, KEY, VALUE) +! ***************************************************************************** + IMPLICIT NONE + CHARACTER(LEN=*), INTENT(IN) :: LINE + CHARACTER(LEN=256), INTENT(OUT) :: KEY, VALUE + INTEGER :: POS + + ! FIND POSITION OF '=' CHARACTER + POS = INDEX(LINE, '=') + IF (POS > 0) THEN + KEY = TRIM(ADJUSTL(LINE(1:POS-1))) + VALUE = TRIM(ADJUSTL(LINE(POS+1:))) + ELSE + KEY = '' + VALUE = '' + ENDIF + +! ***************************************************************************** +END SUBROUTINE SPLIT_LINE +! ***************************************************************************** + +! ***************************************************************************** +SUBROUTINE PARSE_MAP_INFO(MAP_INFO_STR, MAP_INFO_PARAMS) +! ***************************************************************************** + IMPLICIT NONE + CHARACTER(LEN=*), INTENT(IN) :: MAP_INFO_STR + CHARACTER(LEN=256), DIMENSION(7), INTENT(OUT) :: MAP_INFO_PARAMS + CHARACTER(LEN=256) :: TEMP_STR + INTEGER :: I, N + + ! REMOVE BRACES AND SPLIT BY COMMAS + TEMP_STR = MAP_INFO_STR + TEMP_STR = TRIM(ADJUSTL(TEMP_STR)) + TEMP_STR = TEMP_STR(2:LEN(TEMP_STR)-1) ! REMOVE '{' AND '}' + + N = 1 + DO I = 1, 7 + CALL GET_NEXT_VALUE(TEMP_STR, MAP_INFO_PARAMS(I), N) + END DO +! ***************************************************************************** +END SUBROUTINE PARSE_MAP_INFO +! ***************************************************************************** + +! ***************************************************************************** +SUBROUTINE GET_NEXT_VALUE(STR, VALUE, START_POS) +! ***************************************************************************** + IMPLICIT NONE + CHARACTER(LEN=*), INTENT(IN) :: STR + CHARACTER(LEN=256), INTENT(OUT) :: VALUE + INTEGER, INTENT(INOUT) :: START_POS + INTEGER :: END_POS + + END_POS = INDEX(STR(START_POS:), ',') + IF (END_POS > 0) THEN + VALUE = TRIM(STR(START_POS:START_POS+END_POS-2)) + START_POS = START_POS + END_POS + ELSE + VALUE = TRIM(STR(START_POS:)) + START_POS = LEN(STR) + 1 + ENDIF +! ***************************************************************************** +END SUBROUTINE GET_NEXT_VALUE +! ***************************************************************************** + ! ***************************************************************************** END MODULE ELMFIRE_IO ! ***************************************************************************** From b2b53dc5dd57558d57b908a5004bb67d1c028c38 Mon Sep 17 00:00:00 2001 From: Ryan McCarthy Date: Fri, 10 Jan 2025 10:51:38 -0700 Subject: [PATCH 2/2] simplifiying the HDR parsing to something simpler and fixing a bug with the MISC dir parsing --- build/source/elmfire.f90 | 4 +- build/source/elmfire_io.f90 | 468 +++++++++++++---------------- build/source/elmfire_namelists.f90 | 10 +- 3 files changed, 220 insertions(+), 262 deletions(-) diff --git a/build/source/elmfire.f90 b/build/source/elmfire.f90 index 0211582..abf6277 100644 --- a/build/source/elmfire.f90 +++ b/build/source/elmfire.f90 @@ -175,11 +175,11 @@ PROGRAM ELMFIRE ENDIF ELSE IF (IRANK_WORLD .EQ. PARALLEL_IO_RANK(1)) THEN - CALL READ_BSQ_HEADER (ASP, FUELS_AND_TOPOGRAPHY_DIRECTORY, ASP_FILENAME, .FALSE.) + CALL READ_BSQ_HDR_HEADER (ASP, FUELS_AND_TOPOGRAPHY_DIRECTORY, ASP_FILENAME, .FALSE.) ENDIF IF (IRANK_WORLD .EQ. PARALLEL_IO_RANK(2)) THEN - CALL READ_BSQ_HEADER (WS , WEATHER_DIRECTORY , WS_FILENAME , .FALSE.) + CALL READ_BSQ_HDR_HEADER (WS , WEATHER_DIRECTORY , WS_FILENAME , .FALSE.) ENDIF ENDIF diff --git a/build/source/elmfire_io.f90 b/build/source/elmfire_io.f90 index 242d83f..603a77b 100644 --- a/build/source/elmfire_io.f90 +++ b/build/source/elmfire_io.f90 @@ -985,6 +985,136 @@ SUBROUTINE READ_BSQ_HEADER(RASTER,INDIR,FN,DELETE_INTERMEDIATE_FILES) END SUBROUTINE READ_BSQ_HEADER ! ***************************************************************************** +! ***************************************************************************** +SUBROUTINE READ_BSQ_HDR_HEADER(RASTER,INDIR,FN,DELETE_INTERMEDIATE_FILES) +! ***************************************************************************** + +#ifdef __INTEL_COMPILER +USE IFPORT +#endif + +TYPE (RASTER_TYPE) :: RASTER +CHARACTER(400), INTENT (IN) :: INDIR,FN +LOGICAL, INTENT(IN) :: DELETE_INTERMEDIATE_FILES +CHARACTER(400) :: FNHDR, FNBSQ, FNTIF, SHELLSTR +INTEGER :: ISTAT + +! Parsed ENVI HDR variables +INTEGER :: SAMPLES, LINES, BANDS, DATA_TYPE, HEADER_OFFSET, BYTE_ORDER +REAL :: DATA_IGNORE_VALUE, X_PIXEL_REFERENCE, Y_PIXEL_REFERENCE +REAL :: EASTING, NORTHING, X_PIXEL_SIZE, Y_PIXEL_SIZE +CHARACTER(3) :: INTERLEAVE +CHARACTER(1024) :: COORDINATE_SYSTEM, DESCRIPTION +CHARACTER(1024) :: DEFAULT_BANDS, BAND_NAMES +CHARACTER(64) :: FILE_TYPE, PROJECTION_NAME + +IF (VRT_INSTEAD_OF_TIF) THEN + FNTIF = TRIM(INDIR) // TRIM(FN) // '.vrt' +ELSE + FNTIF = TRIM(INDIR) // TRIM(FN) // '.tif' +ENDIF + +print *, "scratch dir value: ", TRIM(SCRATCH) + +IF (TRIM(SCRATCH) .EQ. 'null') THEN + FNHDR = TRIM(INDIR) // TRIM(FN) // '.hdr' + FNBSQ = TRIM(INDIR) // TRIM(FN) // '.bsq' +ELSE + FNHDR = TRIM(SCRATCH) // TRIM(FN) // '.hdr' + FNBSQ = TRIM(SCRATCH) // TRIM(FN) // '.bsq' +ENDIF + +! Convert to ENVI header BSQ format +IF (.NOT. USE_EXISTING_BSQS) THEN + SHELLSTR = TRIM(PATH_TO_GDAL) // 'gdal_translate -of ENVI -co "INTERLEAVE=BSQ" ' // TRIM(FNTIF) // " " // TRIM(FNBSQ) + WRITE(*,100) TRIM(SHELLSTR); CALL EXECUTE_COMMAND_LINE(TRIM(SHELLSTR)) +ENDIF + +CALL PARSE_ENVI_HEADER(FNHDR, DESCRIPTION, SAMPLES, LINES, BANDS, HEADER_OFFSET, FILE_TYPE, DATA_TYPE, INTERLEAVE, BYTE_ORDER, BAND_NAMES, COORDINATE_SYSTEM, DATA_IGNORE_VALUE, DEFAULT_BANDS, PROJECTION_NAME, X_PIXEL_REFERENCE, Y_PIXEL_REFERENCE, EASTING, NORTHING, X_PIXEL_SIZE, Y_PIXEL_SIZE) + +! WRITE(*,*) 'Dumped HDR params: ' +! WRITE(*,*) ' DESCRIPTION: ', DESCRIPTION +! WRITE(*,*) ' SAMPLES: ', SAMPLES +! WRITE(*,*) ' LINES: ', LINES +! WRITE(*,*) ' BANDS: ', BANDS +! WRITE(*,*) ' HEADER_OFFSET: ', HEADER_OFFSET +! WRITE(*,*) ' FILE_TYPE: ', FILE_TYPE +! WRITE(*,*) ' DATA_TYPE: ', DATA_TYPE +! WRITE(*,*) ' INTERLEAVE: ', INTERLEAVE +! WRITE(*,*) ' BYTE_ORDER: ', BYTE_ORDER +! WRITE(*,*) ' BAND_NAMES: ', BAND_NAMES +! WRITE(*,*) ' COORDINATE_SYSTEM: ', COORDINATE_SYSTEM +! WRITE(*,*) ' DATA_IGNORE_VALUE: ', DATA_IGNORE_VALUE +! WRITE(*,*) ' DEFAULT_BANDS: ', DEFAULT_BANDS +! WRITE(*,*) ' PROJECTION_NAME: ', PROJECTION_NAME +! WRITE(*,*) ' X_PIXEL_REFERENCE: ', X_PIXEL_REFERENCE +! WRITE(*,*) ' Y_PIXEL_REFERENCE: ', Y_PIXEL_REFERENCE +! WRITE(*,*) ' EASTING: ', EASTING +! WRITE(*,*) ' NORTHING: ', NORTHING +! WRITE(*,*) ' X_PIXEL_SIZE: ', X_PIXEL_SIZE +! WRITE(*,*) ' Y_PIXEL_SIZE: ', Y_PIXEL_SIZE + +! These values should always be set +RASTER%NROWS = LINES +RASTER%NCOLS = SAMPLES +RASTER%NODATA_VALUE = DATA_IGNORE_VALUE +RASTER%XDIM = X_PIXEL_SIZE +RASTER%YDIM = Y_PIXEL_SIZE +RASTER%XLLCORNER = EASTING +RASTER%YLLCORNER = NORTHING - Y_PIXEL_SIZE * LINES +RASTER%LAYOUT = INTERLEAVE + +SELECT CASE(TRIM(INTERLEAVE)) + CASE('BIL') + RASTER%BYTEORDER = 'I' + CASE('BSQ') + RASTER%BYTEORDER = '0' +END SELECT + + +SELECT CASE(DATA_TYPE) + CASE(2) + RASTER%PIXELTYPE='SIGNEDINT' + RASTER%NBITS=16 + CASE(4) + RASTER%PIXELTYPE='FLOAT' + RASTER%NBITS=32 +END SELECT + +! Check to make sure x and y cell sizes are the same: +IF (RASTER%XDIM .NE. RASTER%YDIM) THEN + WRITE(*,*) 'Error opening ', TRIM(FNHDR), ' because XDIM is not equal to YDIM.' + STOP +ELSE + RASTER%CELLSIZE=RASTER%XDIM +ENDIF + +! Need to handle some defaults +IF (BANDS .LT. 0) THEN + RASTER%NBANDS = 1 +ELSE + RASTER%NBANDS = BANDS +ENDIF + +! Set BANDROWBYTES and TOTALROWBYTES: +RASTER%BANDROWBYTES = (RASTER%NBITS/8) * RASTER%NCOLS +RASTER%TOTALROWBYTES = RASTER%BANDROWBYTES * RASTER%NBANDS + +! Set ULXMAP and ULYMAP +RASTER%ULXMAP = RASTER%XLLCORNER + 0.5 * RASTER%CELLSIZE +RASTER%ULYMAP = RASTER%YLLCORNER + RASTER%NROWS * RASTER%CELLSIZE - 0.5 * RASTER%CELLSIZE + +IF (DELETE_INTERMEDIATE_FILES) THEN + SHELLSTR = TRIM(DELETECOMMAND) // " " // TRIM(FNBSQ) // " " // TRIM(FNHDR) + WRITE(*,100) TRIM(SHELLSTR); ISTAT = SYSTEM(TRIM(SHELLSTR)) +ENDIF + +100 FORMAT(A) + +! ***************************************************************************** +END SUBROUTINE READ_BSQ_HDR_HEADER +! ***************************************************************************** + ! ***************************************************************************** SUBROUTINE READ_BSQ_HEADER_EXISTING_TILED(RASTER,FNIN) ! ***************************************************************************** @@ -1087,24 +1217,14 @@ SUBROUTINE READ_BSQ_RASTER(RASTER,INDIR,FN) TYPE (RASTER_TYPE) :: RASTER CHARACTER(400), INTENT (IN) :: INDIR,FN -CHARACTER(400) :: FNHDR, FNBSQ, FNTIF, FNPRJ, FNXML, SHELLSTR, TEMPSTR -INTEGER :: I, J, IOS, IBAND, ISTAT, ITYPE, IDUMMY, IROW1, IROW2 +CHARACTER(400) :: FNHDR, FNBSQ, FNTIF +INTEGER :: IOS, IBAND, IROW1, IROW2 INTEGER*8 :: LRECL -LOGICAL :: FOUND REAL, ALLOCATABLE, DIMENSION(:) :: RVALUES REAL, ALLOCATABLE, DIMENSION(:,:) :: RTEMP INTEGER*2, ALLOCATABLE, DIMENSION(:) :: I2VALUES INTEGER*2, ALLOCATABLE, DIMENSION(:,:) :: I2TEMP -! Parsed ENVI HDR variables -INTEGER :: SAMPLES, LINES, BANDS, DATA_TYPE, HEADER_OFFSET, BYTE_ORDER -REAL :: DATA_IGNORE_VALUE, X_PIXEL_REFERENCE, Y_PIXEL_REFERENCE -REAL :: EASTING, NORTHING, X_PIXEL_SIZE, Y_PIXEL_SIZE -CHARACTER(3) :: INTERLEAVE -CHARACTER(1024) :: COORDINATE_SYSTEM, DESCRIPTION -CHARACTER(1024) :: DEFAULT_BANDS, BAND_NAMES -CHARACTER(64) :: FILE_TYPE, PROJECTION_NAME - IF (VRT_INSTEAD_OF_TIF) THEN FNTIF = TRIM(INDIR) // TRIM(FN) // '.vrt' ELSE @@ -1114,74 +1234,12 @@ SUBROUTINE READ_BSQ_RASTER(RASTER,INDIR,FN) IF (TRIM(SCRATCH) .EQ. 'null') THEN FNHDR = TRIM(INDIR) // TRIM(FN) // '.hdr' FNBSQ = TRIM(INDIR) // TRIM(FN) // '.bsq' - FNPRJ = TRIM(INDIR) // TRIM(FN) // '.prj' - FNXML = TRIM(FNBSQ) // '.aux.xml' ELSE FNHDR = TRIM(SCRATCH) // TRIM(FN) // '.hdr' FNBSQ = TRIM(SCRATCH) // TRIM(FN) // '.bsq' - FNPRJ = TRIM(SCRATCH) // TRIM(FN) // '.prj' - FNXML = TRIM(FNBSQ) // '.aux.xml' ENDIF -! Convert to ENVI header BSQ format -IF (.NOT. USE_EXISTING_BSQS) THEN - SHELLSTR = TRIM(DELETECOMMAND) // " " // TRIM(FNBSQ) // " " // TRIM(FNHDR) // " " // TRIM(FNPRJ) // " " // TRIM(FNXML) - WRITE(*,100) TRIM(SHELLSTR); ISTAT = SYSTEM(TRIM(SHELLSTR)) - SHELLSTR = TRIM(PATH_TO_GDAL) // 'gdal_translate -of ENVI -co "INTERLEAVE=BSQ" ' // TRIM(FNTIF) // " " // TRIM(FNBSQ) - WRITE(*,100) TRIM(SHELLSTR); CALL EXECUTE_COMMAND_LINE(TRIM(SHELLSTR)) -ENDIF - -CALL PARSE_ENVI_HEADER(FNHDR, DESCRIPTION, SAMPLES, LINES, BANDS, HEADER_OFFSET, FILE_TYPE, DATA_TYPE, INTERLEAVE, BYTE_ORDER, BAND_NAMES, COORDINATE_SYSTEM, DATA_IGNORE_VALUE, DEFAULT_BANDS, PROJECTION_NAME, X_PIXEL_REFERENCE, Y_PIXEL_REFERENCE, EASTING, NORTHING, X_PIXEL_SIZE, Y_PIXEL_SIZE) - -! These values should always be set -RASTER%NROWS = LINES -RASTER%NCOLS = SAMPLES -RASTER%NODATA_VALUE = DATA_IGNORE_VALUE -RASTER%XDIM = X_PIXEL_SIZE -RASTER%YDIM = Y_PIXEL_SIZE -RASTER%XLLCORNER = EASTING -RASTER%YLLCORNER = NORTHING - Y_PIXEL_SIZE * LINES -RASTER%LAYOUT = INTERLEAVE - -SELECT CASE(TRIM(INTERLEAVE)) - CASE('BIL') - RASTER%BYTEORDER = 'I' - CASE('BSQ') - RASTER%BYTEORDER = '0' -END SELECT - - -SELECT CASE(DATA_TYPE) - CASE(2) - RASTER%PIXELTYPE='SIGNEDINT' - RASTER%NBITS=16 - CASE(4) - RASTER%PIXELTYPE='FLOAT' - RASTER%NBITS=32 -END SELECT - -! Check to make sure x and y cell sizes are the same: -IF (RASTER%XDIM .NE. RASTER%YDIM) THEN - WRITE(*,*) 'Error opening ', TRIM(FNHDR), ' because XDIM is not equal to YDIM.' - STOP -ELSE - RASTER%CELLSIZE=RASTER%XDIM -ENDIF - -! Need to handle some defaults -IF (BANDS .LT. 0) THEN - RASTER%NBANDS = 1 -ELSE - RASTER%NBANDS = BANDS -ENDIF - -! Set BANDROWBYTES and TOTALROWBYTES: -RASTER%BANDROWBYTES = (RASTER%NBITS/8) * RASTER%NCOLS -RASTER%TOTALROWBYTES = RASTER%BANDROWBYTES * RASTER%NBANDS - -! Set ULXMAP and ULYMAP -RASTER%ULXMAP = RASTER%XLLCORNER + 0.5 * RASTER%CELLSIZE -RASTER%ULYMAP = RASTER%YLLCORNER + RASTER%NROWS * RASTER%CELLSIZE - 0.5 * RASTER%CELLSIZE +CALL READ_BSQ_HDR_HEADER(RASTER, INDIR, FN, .FALSE.) SELECT CASE(TRIM(RASTER%PIXELTYPE)) @@ -2154,214 +2212,108 @@ END SUBROUTINE WRITE_NODE ! ***************************************************************************** SUBROUTINE PARSE_ENVI_HEADER(HDR_FILE_NAME, DESCRIPTION, SAMPLES, LINES, BANDS, HEADER_OFFSET, FILE_TYPE, DATA_TYPE, INTERLEAVE, BYTE_ORDER, BAND_NAMES, COORDINATE_SYSTEM, DATA_IGNORE_VALUE, DEFAULT_BANDS, PROJECTION_NAME, X_PIXEL_REFERENCE, Y_PIXEL_REFERENCE, EASTING, NORTHING, X_PIXEL_SIZE, Y_PIXEL_SIZE) ! ***************************************************************************** - IMPLICIT NONE - CHARACTER(LEN=*), INTENT(IN) :: HDR_FILE_NAME - INTEGER, INTENT(OUT) :: SAMPLES, LINES, BANDS, DATA_TYPE - INTEGER, INTENT(OUT) :: HEADER_OFFSET, BYTE_ORDER - REAL, INTENT(OUT) :: DATA_IGNORE_VALUE - CHARACTER(LEN=3), INTENT(OUT) :: INTERLEAVE - CHARACTER(LEN=1024), INTENT(OUT) :: COORDINATE_SYSTEM, DESCRIPTION - CHARACTER(LEN=1024), INTENT(OUT) :: DEFAULT_BANDS, BAND_NAMES - CHARACTER(LEN=64), INTENT(OUT) :: FILE_TYPE - ! Map Info Parameters - CHARACTER(64), INTENT(OUT) :: PROJECTION_NAME - REAL, INTENT(OUT) :: X_PIXEL_REFERENCE - REAL, INTENT(OUT) :: Y_PIXEL_REFERENCE - REAL, INTENT(OUT) :: EASTING - REAL, INTENT(OUT) :: NORTHING - REAL, INTENT(OUT) :: X_PIXEL_SIZE - REAL, INTENT(OUT) :: Y_PIXEL_SIZE - - CHARACTER(LEN=256), DIMENSION(7) :: MAP_INFO_PARAMS - CHARACTER(LEN=1024) :: LINE, CURRENT_KEY, CURRENT_VALUE - INTEGER :: IUNIT, IOS - LOGICAL :: READING_MULTILINE_VALUE, FOUND_SAMPLES, FOUND_LINES, FOUND_BANDS - LOGICAL :: FOUND_DATA_TYPE, FOUND_BYTE_ORDER, FOUND_DATA_IGNORE_VALUE - LOGICAL :: FOUND_MAP_INFO, FOUND_COORDINATE_SYSTEM, FOUND_DESCRIPTION - LOGICAL :: FOUND_FILE_TYPE, FOUND_DEFAULT_BANDS, FOUND_INTERLEAVE - LOGICAL :: FOUND_HEADER_OFFSET, FOUND_BAND_NAMES - - ! INITIALIZE FLAGS AND DEFAULT VALUES - READING_MULTILINE_VALUE = .FALSE. - FOUND_DESCRIPTION = .FALSE. - FOUND_SAMPLES = .FALSE. - FOUND_LINES = .FALSE. - FOUND_BANDS = .FALSE. - FOUND_HEADER_OFFSET = .FALSE. - FOUND_FILE_TYPE = .FALSE. - FOUND_DATA_TYPE = .FALSE. - FOUND_INTERLEAVE = .FALSE. - FOUND_BYTE_ORDER = .FALSE. - FOUND_MAP_INFO = .FALSE. - FOUND_COORDINATE_SYSTEM = .FALSE. - FOUND_BAND_NAMES = .FALSE. - FOUND_DATA_IGNORE_VALUE = .FALSE. - FOUND_DEFAULT_BANDS = .FALSE. - - ! OPEN THE FILE - OPEN(UNIT=10, FILE=HDR_FILE_NAME, STATUS='OLD', ACTION='READ', IOSTAT=IOS) - IF (IOS /= 0) THEN - PRINT *, 'ERROR OPENING HDR FILE: ', HDR_FILE_NAME - RETURN - ENDIF +IMPLICIT NONE +CHARACTER(LEN=*), INTENT(IN) :: HDR_FILE_NAME +INTEGER, INTENT(OUT) :: SAMPLES, LINES, BANDS, HEADER_OFFSET, DATA_TYPE, BYTE_ORDER +REAL, INTENT(OUT) :: DATA_IGNORE_VALUE, EASTING, NORTHING, X_PIXEL_SIZE, Y_PIXEL_SIZE, X_PIXEL_REFERENCE, Y_PIXEL_REFERENCE +CHARACTER(3), INTENT(OUT) :: INTERLEAVE +CHARACTER(1024), INTENT(OUT) :: COORDINATE_SYSTEM, DESCRIPTION +CHARACTER(1024), INTENT(OUT) :: DEFAULT_BANDS, BAND_NAMES +CHARACTER(64), INTENT(OUT) :: FILE_TYPE, PROJECTION_NAME + +CHARACTER(LEN=1024) :: LINE, KEY, CURRENT_VALUE +INTEGER :: I, POS, IOS +LOGICAL :: IN_MULTILINE +CHARACTER(LEN=:), ALLOCATABLE :: MULTILINE_VALUE + +CHARACTER(LEN=256) :: MAP_INFO + +IN_MULTILINE = .FALSE. +MULTILINE_VALUE = '' + +OPEN(UNIT=10, FILE=HDR_FILE_NAME, STATUS='OLD', ACTION='READ', IOSTAT=IOS) +IF (IOS /= 0) THEN + PRINT *, 'ERROR OPENING HDR FILE: ', HDR_FILE_NAME + STOP +ENDIF - ! LOOP THROUGH EACH LINE IN THE FILE - DO - READ(10, '(A)', IOSTAT=IOS) LINE - IF (IOS /= 0) EXIT - IF (READING_MULTILINE_VALUE) THEN - ! CONTINUE READING UNTIL THE MULTILINE VALUE ENDS - IF (INDEX(LINE, '}') > 0) THEN - CURRENT_VALUE = TRIM(CURRENT_VALUE) // ' ' // TRIM(ADJUSTL(LINE)) - READING_MULTILINE_VALUE = .FALSE. - ELSE - CURRENT_VALUE = TRIM(CURRENT_VALUE) // ' ' // TRIM(ADJUSTL(LINE)) - CYCLE - ENDIF +DO + READ(10, '(A)', IOSTAT=I) LINE + IF (I /= 0) EXIT + + IF (IN_MULTILINE) THEN + IF (INDEX(LINE, '}') > 0) THEN + MULTILINE_VALUE = MULTILINE_VALUE // ' ' // TRIM(ADJUSTL(LINE(1:INDEX(LINE, '}')-1))) + IN_MULTILINE = .FALSE. + !CALL ASSIGN_VALUE(KEY, TRIM(MULTILINE_VALUE), MAP_INFO) + CURRENT_VALUE = TRIM(MULTILINE_VALUE) ELSE - CALL SPLIT_LINE(LINE, CURRENT_KEY, CURRENT_VALUE) + MULTILINE_VALUE = MULTILINE_VALUE // ' ' // TRIM(ADJUSTL(LINE)) + ENDIF + ELSE + POS = INDEX(LINE, '=') + IF (POS > 0) THEN + KEY = TRIM(ADJUSTL(LINE(1:POS-1))) + CURRENT_VALUE = TRIM(ADJUSTL(LINE(POS+1:))) IF (INDEX(CURRENT_VALUE, '{') > 0 .AND. INDEX(CURRENT_VALUE, '}') == 0) THEN - READING_MULTILINE_VALUE = .TRUE. - CYCLE + IN_MULTILINE = .TRUE. + MULTILINE_VALUE = TRIM(ADJUSTL(CURRENT_VALUE(INDEX(CURRENT_VALUE, '{')+1:))) + ELSE IF (INDEX(CURRENT_VALUE, '{') > 0) THEN + !CALL ASSIGN_VALUE(KEY, TRIM(VALUE(INDEX(VALUE, '{')+1:INDEX(VALUE, '}')-1)), MAP_INFO) + CURRENT_VALUE = TRIM(CURRENT_VALUE(INDEX(CURRENT_VALUE, '{')+1:INDEX(CURRENT_VALUE, '}')-1)) ENDIF ENDIF + ENDIF + +! print *, "HDR line: ", TRIM(ADJUSTL(LINE)), "ENDLINE" +! print *, " HDR key: ", TRIM(ADJUSTL(KEY)), "ENDKEY" +! print *, " HDR value: ", TRIM(ADJUSTL(CURRENT_VALUE)), "ENDVALUE" + + CURRENT_VALUE = TRIM(ADJUSTL(CURRENT_VALUE)) - ! MATCH KEY TO EXPECTED VARIABLES AND STORE VALUES - SELECT CASE (TRIM(ADJUSTL(CURRENT_KEY))) + SELECT CASE (TRIM(ADJUSTL(KEY))) CASE ('description') - DESCRIPTION = TRIM(ADJUSTL(CURRENT_VALUE)); FOUND_DESCRIPTION = .TRUE. + DESCRIPTION = CURRENT_VALUE CASE ('samples') - READ(CURRENT_VALUE, *) SAMPLES; FOUND_SAMPLES = .TRUE. + READ(CURRENT_VALUE, *) SAMPLES CASE ('lines') - READ(CURRENT_VALUE, *) LINES; FOUND_LINES = .TRUE. + READ(CURRENT_VALUE, *) LINES CASE ('bands') - READ(CURRENT_VALUE, *) BANDS; FOUND_BANDS = .TRUE. + READ(CURRENT_VALUE, *) BANDS CASE ('header offset') - READ(CURRENT_VALUE, *) HEADER_OFFSET; FOUND_HEADER_OFFSET = .TRUE. + READ(CURRENT_VALUE, *) HEADER_OFFSET CASE ('file type') - FILE_TYPE = TRIM(ADJUSTL(CURRENT_VALUE)); FOUND_FILE_TYPE = .TRUE. + FILE_TYPE = CURRENT_VALUE CASE ('data type') - READ(CURRENT_VALUE, *) DATA_TYPE; FOUND_DATA_TYPE = .TRUE. + READ(CURRENT_VALUE, *) DATA_TYPE CASE ('interleave') - INTERLEAVE = TRIM(ADJUSTL(CURRENT_VALUE)); FOUND_INTERLEAVE = .TRUE. + INTERLEAVE = CURRENT_VALUE CASE ('byte order') - READ(CURRENT_VALUE, *) BYTE_ORDER; FOUND_BYTE_ORDER = .TRUE. + READ(CURRENT_VALUE, *) BYTE_ORDER CASE ('map info') - CALL PARSE_MAP_INFO(TRIM(CURRENT_VALUE), MAP_INFO_PARAMS) - FOUND_MAP_INFO = .TRUE. - READ(MAP_INFO_PARAMS(1), *) PROJECTION_NAME - READ(MAP_INFO_PARAMS(2), *) X_PIXEL_REFERENCE - READ(MAP_INFO_PARAMS(3), *) Y_PIXEL_REFERENCE - READ(MAP_INFO_PARAMS(4), *) EASTING - READ(MAP_INFO_PARAMS(5), *) NORTHING - READ(MAP_INFO_PARAMS(6), *) X_PIXEL_SIZE - READ(MAP_INFO_PARAMS(7), *) Y_PIXEL_SIZE - CASE ('coordinate system string') - COORDINATE_SYSTEM = TRIM(ADJUSTL(CURRENT_VALUE)); FOUND_COORDINATE_SYSTEM = .TRUE. + MAP_INFO = CURRENT_VALUE + CASE ('coordinate system') + COORDINATE_SYSTEM = CURRENT_VALUE CASE ('band names') - BAND_NAMES = TRIM(ADJUSTL(CURRENT_VALUE)); FOUND_BAND_NAMES = .TRUE. + BAND_NAMES = CURRENT_VALUE CASE ('data ignore value') - READ(CURRENT_VALUE, *) DATA_IGNORE_VALUE; FOUND_DATA_IGNORE_VALUE = .TRUE. + READ(CURRENT_VALUE, *) DATA_IGNORE_VALUE CASE ('default bands') - DEFAULT_BANDS = TRIM(ADJUSTL(CURRENT_VALUE)); FOUND_DEFAULT_BANDS = .TRUE. - END SELECT - END DO - - ! CLOSE THE FILE - CLOSE(10) - - ! SET DEFAULT VALUES FOR MISSING VARIABLES - IF (.NOT. FOUND_DESCRIPTION) DESCRIPTION = 'UNKNOWN' - IF (.NOT. FOUND_SAMPLES) SAMPLES = -1 - IF (.NOT. FOUND_LINES) LINES = -1 - IF (.NOT. FOUND_BANDS) BANDS = 1 - IF (.NOT. FOUND_HEADER_OFFSET) HEADER_OFFSET = 0 - IF (.NOT. FOUND_FILE_TYPE) FILE_TYPE = 'UNKNOWN' - IF (.NOT. FOUND_DATA_TYPE) DATA_TYPE = -1 - IF (.NOT. FOUND_INTERLEAVE) INTERLEAVE = 'UNKNOWN' - IF (.NOT. FOUND_BYTE_ORDER) BYTE_ORDER = -1 - IF (.NOT. FOUND_MAP_INFO) THEN - PROJECTION_NAME = "UNKNOWN" - X_PIXEL_REFERENCE = 1 - Y_PIXEL_REFERENCE = 1 - EASTING = 0 - NORTHING = 0 - X_PIXEL_SIZE = 0 - Y_PIXEL_SIZE = 0 - ENDIF - IF (.NOT. FOUND_COORDINATE_SYSTEM) COORDINATE_SYSTEM = 'UNKNOWN' - IF (.NOT. FOUND_BAND_NAMES) BAND_NAMES = 'UNKNOWN' - IF (.NOT. FOUND_DATA_IGNORE_VALUE) DATA_IGNORE_VALUE = -9999.0 - IF (.NOT. FOUND_DEFAULT_BANDS) DEFAULT_BANDS = 'UNKNOWN' - -! ***************************************************************************** -END SUBROUTINE PARSE_ENVI_HEADER -! ***************************************************************************** - -! ***************************************************************************** -SUBROUTINE SPLIT_LINE(LINE, KEY, VALUE) -! ***************************************************************************** - IMPLICIT NONE - CHARACTER(LEN=*), INTENT(IN) :: LINE - CHARACTER(LEN=256), INTENT(OUT) :: KEY, VALUE - INTEGER :: POS - - ! FIND POSITION OF '=' CHARACTER - POS = INDEX(LINE, '=') - IF (POS > 0) THEN - KEY = TRIM(ADJUSTL(LINE(1:POS-1))) - VALUE = TRIM(ADJUSTL(LINE(POS+1:))) - ELSE - KEY = '' - VALUE = '' - ENDIF - -! ***************************************************************************** -END SUBROUTINE SPLIT_LINE -! ***************************************************************************** + DEFAULT_BANDS = CURRENT_VALUE + END SELECT -! ***************************************************************************** -SUBROUTINE PARSE_MAP_INFO(MAP_INFO_STR, MAP_INFO_PARAMS) -! ***************************************************************************** - IMPLICIT NONE - CHARACTER(LEN=*), INTENT(IN) :: MAP_INFO_STR - CHARACTER(LEN=256), DIMENSION(7), INTENT(OUT) :: MAP_INFO_PARAMS - CHARACTER(LEN=256) :: TEMP_STR - INTEGER :: I, N +END DO - ! REMOVE BRACES AND SPLIT BY COMMAS - TEMP_STR = MAP_INFO_STR - TEMP_STR = TRIM(ADJUSTL(TEMP_STR)) - TEMP_STR = TEMP_STR(2:LEN(TEMP_STR)-1) ! REMOVE '{' AND '}' +CLOSE(10) - N = 1 - DO I = 1, 7 - CALL GET_NEXT_VALUE(TEMP_STR, MAP_INFO_PARAMS(I), N) - END DO -! ***************************************************************************** -END SUBROUTINE PARSE_MAP_INFO -! ***************************************************************************** +! PARSE MAP_INFO INTO INDIVIDUAL COMPONENTS +IF (TRIM(MAP_INFO) /= '') THEN + READ(MAP_INFO, *, IOSTAT=I) PROJECTION_NAME, X_PIXEL_REFERENCE, Y_PIXEL_REFERENCE, EASTING, NORTHING, X_PIXEL_SIZE, Y_PIXEL_SIZE +END IF ! ***************************************************************************** -SUBROUTINE GET_NEXT_VALUE(STR, VALUE, START_POS) -! ***************************************************************************** - IMPLICIT NONE - CHARACTER(LEN=*), INTENT(IN) :: STR - CHARACTER(LEN=256), INTENT(OUT) :: VALUE - INTEGER, INTENT(INOUT) :: START_POS - INTEGER :: END_POS - - END_POS = INDEX(STR(START_POS:), ',') - IF (END_POS > 0) THEN - VALUE = TRIM(STR(START_POS:START_POS+END_POS-2)) - START_POS = START_POS + END_POS - ELSE - VALUE = TRIM(STR(START_POS:)) - START_POS = LEN(STR) + 1 - ENDIF -! ***************************************************************************** -END SUBROUTINE GET_NEXT_VALUE +END SUBROUTINE PARSE_ENVI_HEADER ! ***************************************************************************** ! ***************************************************************************** diff --git a/build/source/elmfire_namelists.f90 b/build/source/elmfire_namelists.f90 index 3ede955..814a838 100644 --- a/build/source/elmfire_namelists.f90 +++ b/build/source/elmfire_namelists.f90 @@ -29,9 +29,15 @@ SUBROUTINE READ_MISC STOP ENDIF -MISCELLANEOUS_INPUTS_DIRECTORY = TRIM(MISCELLANEOUS_INPUTS_DIRECTORY) // PATH_SEPARATOR PATH_TO_GDAL = TRIM(PATH_TO_GDAL ) // PATH_SEPARATOR -SCRATCH = TRIM(SCRATCH ) // PATH_SEPARATOR + +! if dirs are still null don't add a path separator +IF (MISCELLANEOUS_INPUTS_DIRECTORY .NE. 'null') THEN + MISCELLANEOUS_INPUTS_DIRECTORY = TRIM(MISCELLANEOUS_INPUTS_DIRECTORY) // PATH_SEPARATOR +ENDIF +IF (SCRATCH .NE. 'null') THEN + SCRATCH = TRIM(SCRATCH ) // PATH_SEPARATOR +ENDIF ! ***************************************************************************** END SUBROUTINE READ_MISC