Hello,
I am trying to read a bunch of tiffs that were created programmatically with ENVI's layer stacking routine into arrays, but keep getting an error. Turns out when I query_image on one of the tiffs, a 0 is returned, indicating (from
http://www.exelisvis.com/...s/QUERY_IMAGE.html): The return status will indicate failure for files that contain formats that are not supported by the corresponding READ_* routine, even though the file may be valid outside the IDL environment.
I'm not quite clear as to why the ENVI routine is producing images that are not 'valid' inside the IDL environment, but I need to fix it. Looking at the stacked images and their metadata in ENVI, everything points to a normal tiff. Anyone have any idea why this is going on, or more importantly, what I can do to get around it?
Thanks so much.
The bulk of my (uncompleted) code is as follows:
path = 'D:\Maggie Data\TE_Data\'
inpath = path + 'ClassifiedLandsat' + strtrim(string(inputnumber), 2) + '\'
outpath = path + 'ESTP_Outputs\'
; hard code for testing
pr = '063012'
yr = '1990'
yrfolder = inpath + pr + '\' + yr + '\'
inclassfiles = FILE_SEARCH(yrfolder + '*.tif', COUNT = Ndates) ; paths to the individual .tif classified images
print, ' I. Starting Extraction process for epoch ', yr, ', in path/row ', pr
TIC ; start timing the extraction process
for l=0, Ndates - 1 do begin ; L3, go through all individual classified files
inclass = inclassfiles[l] ; path to each individual classified file
date = STRMID(FILE_BASENAME(inclass), 18, 7) ; date for naming extracted files
print, ' Extracting for date #', strtrim((l+1), 2), '. Filename = ', file_basename(inclass)
extractpath = outpath + pr + '\' + yr + '\Extract'
;; A. Query the tiff and return a struct with geo tags, named geotags
ok = query_tiff(inclass, info, geotiff = geotags)
nsamp = info.dimensions[0]
nline = info.dimensions[1]
;; B. read tiff into new array:
classarr = read_tiff(inclass, geotiff = geostruct, photoshop = pshop)
;; C. Create extracted elements arrays:
watarr = bytarr(nsamp, nline) ; new blank arrays
landarr = bytarr(nsamp, nline)
goodarr = bytarr(nsamp, nline)
watarr[WHERE(classarr EQ 5)] = 1 ; generate watarr, filled of 1's and 0's, where 0= not water and 1=water
landarr[WHERE(classarr EQ 6)] = 1 ; generate landarr, where 0 = not clear land and 1 = clear land
goodarr[WHERE(classarr EQ 5)] = 1 ; generate goodarr (for the denominator), where 0 = bad and 1 = good (water or land)
goodarr[WHERE(classarr EQ 6)] = 1 ; also set land pixels to 1
;; D. Write them to new tiffs
wattif = extractpath + 'Water_' + pr + '_' + date + '.tif'
landtif = extractpath + 'Land_' + pr + '_' + date + '.tif'
goodtif = extractpath + 'Good_' + pr + '_' + date + '.tif'
write_tiff, wattif, watarr, geotiff = geostruct, red = [0, 0], blue = [255, 0], green = [0, 0]
write_tiff, landtif, landarr, geotiff = geostruct, red = [255, 0], blue = [255, 0], green = [255, 0]
write_tiff, goodtif, goodarr, geotiff = geostruct, red = [255, 0], blue = [255, 0], green = [255, 0]
endfor ; END L3
print, ' Done with Process I. Total time to perform Extraction on all dates in epoch: ', yr, ', path/row: ', pr, ' = '
TOC ; prints how long entire extraction process took
print, ' '
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; II. STACK ELEMENTS
TIC ; start timing process II.
print, ' II. Starting Stack Process for epoch: ', yr, ', in path/row: ', pr
;; pre. set path variables
Wextract = extractpath + 'Water_' ; inpath for stacks (extracted images)
Lextract = extractpath + 'Land_'
Gextract = extractpath + 'Good_'
stackpath = outpath + pr + '\' + yr + '\Stack' ; outpath for stacks
;; A. Get input parameters and for layer stacking routine
;;; 1. Create a list of the extracted files (one for each element), so DIMS/FID arrays can be got
watfiles= FILE_SEARCH(Wextract + '*.tif') ; create list of .tif water files in epoch folder
landfiles = FILE_SEARCH(Lextract + '*.tif') ; one for all 3 elements
goodfiles = FILE_SEARCH(Gextract + '*.tif')
nlayers = n_elements(watfiles) ; nlayers will be same for all 3
print, nlayers
;;; 2. get 3 FID arrays of length nlayers (aka ndates), and 1 2D array with the dims
;;;; a) create empty arrays to store dims and FIDs
WinstackFID = lonarr(nlayers)
LinstackFID = lonarr(nlayers)
GinstackFID = lonarr(nlayers)
instackDIMS = lonarr(5, nlayers) ; because DIMS returns a 5-element array for each layer, should be same for land
;;;; b) iterate through all dates to build the arrays
for s=0, nlayers-1 do begin ; L4: loop that goes through all extracted tiffs to get dims and FIDs
Winput=watfiles(s) ; Winput is the nlayer to open and get FID from
Linput=landfiles(s)
Ginput=goodfiles(s)
ENVI_OPEN_FILE, Winput, R_FID = WinFID, /invisible ; get FID from water images
WinstackFID(s) += WinFID ;water input FID needs to be different for land (point to land files not water)
ENVI_OPEN_FILE, Linput, R_FID = LinFID, /invisible ; get FID from land images
LinstackFID(s) += LinFID ;build array with FIDs for land layers to be stacked
ENVI_OPEN_FILE, Ginput, R_FID = GinFID, /invisible ; get FID from good images
GinstackFID(s) += GinFID ;build array with FIDs
; query just one list to return the dimensions into a 2-D array (same for water and land)
ENVI_FILE_QUERY, WinstackFID(s), DIMS = inDIM
instackDIMS(*, s) += inDIM ; water and land dims are the same, just need one 2D dimension array for stack input
endfor ; end L4
;help, instackDIMS ; should be arr[5,15]
;;; 3. get the other parameters: projection and position array
instackproj = envi_get_projection (FID = WinstackFID(0)) ; just need one file to get proj info (same for all nlayer*3 files)
instackpos = lonarr(nlayers) ; input pos array needs to be all 0's to point to first band of each stack input
; now we have all 4 inputs needed for layer_stacking: instackDIMS, W/L/GinstackFID, instackproj, instackpos
;; B. Call layer_stacking_doit routine:
;;; 1. Set up output variables:
watstack = stackpath + 'Water_' + pr + '_' + yr + '.tif'
landstack = stackpath + 'Land_' + pr + '_' + yr + '.tif'
goodstack = stackpath + 'Good_' + pr + '_' + yr + '.tif'
;;; 2. Call the routine for all 3 elements:
ENVI_DOIT, 'ENVI_LAYER_STACKING_DOIT', DIMS = instackDIMS, FID= WinstackFID, OUT_DT = 1, $
OUT_NAME= watstack, OUT_PROJ= instackproj, OUT_PS = [30, 30], POS = instackpos, R_FID= WSfid;, /invisible
ENVI_DOIT, 'ENVI_LAYER_STACKING_DOIT', DIMS = instackDIMS, FID= LinstackFID, OUT_DT = 1, $
OUT_NAME= landstack, OUT_PROJ= instackproj, OUT_PS = [30, 30], POS = instackpos, R_FID= LSfid, /invisible
ENVI_DOIT, 'ENVI_LAYER_STACKING_DOIT', DIMS = instackDIMS, FID= GinstackFID, OUT_DT = 1, $
OUT_NAME= goodstack, OUT_PROJ= instackproj, OUT_PS = [30, 30], POS = instackpos, R_FID= GSfid, /invisible
ok2 = query_image(watstack, info2)
print, ok2