Branched from: Help: Batch - composite bands Arc-python
Hi,
I would like use this script, but it fails. Some hint?
import arcpy, os
arcpy.env.workspace = r'C:\Teste_Auto_CLEIA\Ima_compactadas'
# list all folders in a directory
folders = arcpy.ListWorkspaces("L8*", "Folder") # Inside main directory, already have other folders, but the bands are always inside folders that begin with "L8", e.g. "L8227069".
#The output files place
outws = r'C:\Teste_Auto_CLEIA\Imagem' # Line 9
for folder in folders:
arcpy.env.workspace = folder
rasters = arcpy.ListRasters("*.tif") # I already erased the bands which I won't use
chk4 = ['band{0}.tif'.format(i) for i in range(0, 7)] # I changed the range
rasters = [a for a in rasters if a[-9:] in chk4]
name = os.path.join(outws, rasters[1].split("_")[0] + ".tif") # I wrote "outws"
arcpy.CompositeBands_management(rasters, name) # I put it
print(rasters)
I'm using ArcMap 10.1 and the bands names aren't the same, for instance, "LO82270682017183CUB00_B1", ... , "LO82270682017183CUB00_B7".
Thanks!
Solved! Go to Solution.
Can you try this?
import arcpy, os
arcpy.env.workspace = r'C:\Teste_Auto_CLEIA\Ima_compactadas'
# list all folders in a directory
folders = arcpy.ListWorkspaces("L8*", "Folder") # Inside main directory, already have other folders, but the bands are always inside folders that begin with "L8", e.g. "L8227069".
print "folders: "+str(folders) #To see if the search above finds a result
#The output files place
outws = r'C:\Teste_Auto_CLEIA\Imagem' # Line 10
for folder in folders:
arcpy.env.workspace = folder
images = arcpy.ListRasters("L*2*0*_B*.tif") #I changed the user word for an exclusive. This line keeps the bands that I will use
print "images: "+str(images)
## chk4 = ['band{0}.tif'.format(i) for i in range(0, 7)] # I changed the range
## print "chk4: "+str(chk4)
## rasters = [a for a in images if a[-9:] in chk4]
## print "rasters: "+str(rasters)
name = os.path.join(outws, images[0].split("_")[0] + ".tif") # I wrote "outws"
arcpy.CompositeBands_management(images, name) # I put it
print(rasters)
print "Finished" #23
Since you already filtered the folder and removed the images that you don't want to use, there is no need to filter them using lines 16 to 19. The error you were receiving was caused due to trying to extract an item with index 1 from an empty list. The list was empty since you were trying to filter the list using a name "band*" when the bands have a different name (there will be no match).
failure is relative... did you get an error message? and if so, what was it?
indentation on what you have posted is completely wrong, so perhaps you could format the code in case there is an issue in the processing because of it
I tried it. I saw that my line #18 was inside "for folder in folders", while the original wasn't, but none change happens when I fix it.
... print(rasters) #18
The message error still the same.
Runtime error
Traceback (most recent call last):
File "<string>", line 16, in <module>
IndexError: list index out of range
Thanks!
List index out of range means that python was expecting a list of something and the 'index' items in the list are out of range... short translation, list can't list stuff in a folder if you are already in the folder, hence there is nothing to list (ie index is out of range since there is nothing). If you fed in a folder path into a script then it would look in the folder, retriebve the items and cycle through them one by one (ie index from 0 to X)
Can you give more instructions?
I inserted some "prints lines" to show the steps executed correctly and I saw the script finds the first folder and him bands. Besides, I don't understand how the original script is fine and this one isn't.
import arcpy, os
...
... arcpy.env.workspace = r'C:\Teste_Auto_CLEIA\Ima_compactadas'
...
... # list all folders in a directory
... folders = arcpy.ListWorkspaces("L8*", "Folder") # Inside main directory, already have other folders, but the bands are always inside folders that begin with "L8", e.g. "L8227069".
... print "folders: "+str(folders) #To see if the search above finds a result
...
... #The output files place
... outws = r'C:\Teste_Auto_CLEIA\Imagem' # Line 10
...
... for folder in folders:
... arcpy.env.workspace = folder
... images = arcpy.ListRasters("L*2*0*_B*.tif") #I changed the user word for an exclusive. This line keeps the bands that I will use
... print "images: "+str(images)
... chk4 = ['band{0}.tif'.format(i) for i in range(0, 7)] # I changed the range
... print "chk4: "+str(chk4)
... rasters = [a for a in images if a[-9:] in chk4]
... print "rasters: "+str(rasters)
... name = os.path.join(outws, rasters[1].split("_")[0] + ".tif") # I wrote "outws"
... arcpy.CompositeBands_management(rasters, name) # I put it
... print(rasters)
... print "Finished" #23
...
folders: [u'C:\\Teste_Auto_CLEIA\\Ima_compactadas\\L8227068', u'C:\\Teste_Auto_CLEIA\\Ima_compactadas\\L8227069']
images: [u'LO82270682017183CUB00_B1.TIF', u'LO82270682017183CUB00_B2.TIF', u'LO82270682017183CUB00_B3.TIF', u'LO82270682017183CUB00_B4.TIF', u'LO82270682017183CUB00_B5.TIF', u'LO82270682017183CUB00_B6.TIF', u'LO82270682017183CUB00_B7.TIF']
chk4: ['band0.tif', 'band1.tif', 'band2.tif', 'band3.tif', 'band4.tif', 'band5.tif', 'band6.tif']
rasters: []
Runtime error
Traceback (most recent call last):
File "<string>", line 20, in <module>
IndexError: list index out of range
Kind regards.
This slice fails since non of the rasters have the last 9 characters in chk4 (ie 'band0.tif' etc etc)
What are you trying to do with that line? You had better write out what you expect since I can't figure out if you are trying to create a new file name or slice a band to use in line 20.
rasters = [a for a in images if a[-9:] in chk4]
Hi BrunodeDeus , I branched your post to a new question and I have a question if you can provided some additional information before I look at the code, You mention that your band are not named the same, but in the example you included the bands seem to have the same name (apart from 1 and 7). Can you list the rasters that you have and post that list here?
Thanks
Xander Bakker,
I appreciate your help. Right now, I've 2 scenes (some times are more), the folder from a scene (227/068) is showed below.
*I didn't receive the e-mail about your comments, I will set my account to fix it.
Thankful
Can you try this?
import arcpy, os
arcpy.env.workspace = r'C:\Teste_Auto_CLEIA\Ima_compactadas'
# list all folders in a directory
folders = arcpy.ListWorkspaces("L8*", "Folder") # Inside main directory, already have other folders, but the bands are always inside folders that begin with "L8", e.g. "L8227069".
print "folders: "+str(folders) #To see if the search above finds a result
#The output files place
outws = r'C:\Teste_Auto_CLEIA\Imagem' # Line 10
for folder in folders:
arcpy.env.workspace = folder
images = arcpy.ListRasters("L*2*0*_B*.tif") #I changed the user word for an exclusive. This line keeps the bands that I will use
print "images: "+str(images)
## chk4 = ['band{0}.tif'.format(i) for i in range(0, 7)] # I changed the range
## print "chk4: "+str(chk4)
## rasters = [a for a in images if a[-9:] in chk4]
## print "rasters: "+str(rasters)
name = os.path.join(outws, images[0].split("_")[0] + ".tif") # I wrote "outws"
arcpy.CompositeBands_management(images, name) # I put it
print(rasters)
print "Finished" #23
Since you already filtered the folder and removed the images that you don't want to use, there is no need to filter them using lines 16 to 19. The error you were receiving was caused due to trying to extract an item with index 1 from an empty list. The list was empty since you were trying to filter the list using a name "band*" when the bands have a different name (there will be no match).
It works fine!
And the first (and original) script didn't worked to "n" scene(s) just because one line
import arcpy, os
#Define the workspace that contains all of the folders with the Landsat imagery
arcpy.env.workspace = r'C:\Teste_Auto_CLEIA\Ima_compactadas'
#Specify where you would like the output to go
outws = r'C:\Teste_Auto_CLEIA\Imagem'
#List all of the workspaces in the previously defined workspace
folders = arcpy.ListWorkspaces("L8*", "Folder") #Filter to retrieve just the folder(s) with Landsat's bands
#Iterate through this list of workspaces and create a new list within each iteration of unstacked raster bands e.g. ['LC80260272014159LGN00_B1', 'LC80260272014159LGN00_B2',...]
#Landsat files follows this form: LC80260272014159LGN00_B1.tif, so we need to strip off anything after the "_" and use the first basename as the output name. You can do this with various slicing methods and string manipulation in Python.
for folder in folders:
arcpy.env.workspace = folder
rasters = arcpy.ListRasters("L*2*0*_B*.tif")# Filter and does that just the Landsat scenes with path/row from my ROI will be used
name = os.path.join(outws, rasters[1].split("_")[0] + ".tif")
arcpy.CompositeBands_management(rasters, name)
print(rasters)#Line which allows composite bands for "n" scene(s)
# Ao completar, por a frase:
print "Processing complete"
Thank you.