1

I'm trying to go over a folder of geotiff rasters where the last three digits of the raster name is the julian date and I want to append the correct days to monthly lists (Jan-Dec) and then run Cell Statistics on each monthly list of rasters. But I can't get the rasters to append to the monthly lists in Python. I'm using ArcGIS 10.3.1 and Python 2.7.8.

What I have so far isn't working:

import arcpy
from arcpy import sa
from arcpy import env
import glob

directory = myFilePath

lstrasters = glob.glob(directory + os.sep + "*.tif")
lstrasters.sort()
print lstrasters

m1 = [] #empty Jan list
m2 = [] #empty Feb list
m3 = []
m4 = []
m5 = []
m6 = []
m7 = []
m8 = []
m9 = []
m10 = []
m11 = []
m12 = []

for lstras in lstrasters:
    jdate = str(lstras[-7:-4])
    day = int(jdate)
    print day
    sa.Raster(lstras)
    if day in range(1,32):
        m1.append(lstras)
    if day in range(32,60):
        m2.append(lstras)
    if day in range(60,91):
        m3.append(lstras)
    if day in range(91,121):
        m4.append(lstras)
    if day in range(121,152):
        m5.append(lstras)
    if day in range(152,182):
        m6.append(lstras)
    if day in range(182,213):
        m7.append(lstras)
    if day in range(213,244):
        m8.append(lstras)
    if day in range(244,274):
        m9.append(lstras)
    if day in range(274,305):
        m10.append(lstras)
    if day in range(305,335):
        m11.append(lstras)
    if day in range(335,366):
        m12.append(lstras)
    else:
        print "jdate is out of range"

print m1
print m2

....etc.

It prints out the correct jdate day for each raster for sure. But I can't get any of the rasters to append to any of the empty monthly lists that match up to the jdate. it just prints the 'else' statement for each raster saying it is out of range and then prints out each m1,m2,... as empty lists.

What am I doing wrong?

Edit: I changed the day = jdate to day = int(jdate)

Edit 2: Based on the comments, I made the following change to the if/else statements and the script is working properly now.

for lstras in lstrasters:
    jdate = str(lstras[-7:-4])
    day = int(jdate)
    print day
    sa.Raster(lstras)
    if day in range(1,32):
        m1.append(lstras)
    elif day in range(32,60):
        m2.append(lstras)
    elif day in range(60,91):
        m3.append(lstras)
    elif day in range(91,121):
        m4.append(lstras)
    elif day in range(121,152):
        m5.append(lstras)
    elif day in range(152,182):
        m6.append(lstras)
    elif day in range(182,213):
        m7.append(lstras)
    elif day in range(213,244):
        m8.append(lstras)
    elif day in range(244,274):
        m9.append(lstras)
    elif day in range(274,305):
        m10.append(lstras)
    elif day in range(305,335):
        m11.append(lstras)
    elif day in range(335,366):
        m12.append(lstras)
    else:
        print "jdate is out of range"
  • Can you post a couple of the file names? – Tom Mar 31 '16 at 16:57
  • What about leap year? – Richard Morgan Mar 31 '16 at 16:57
  • @RichardMorgan: I have a separate script (almost identical) to handle Leap years. Tom: the raster names are in the format: lst2014001.tif name followed by year followed by 3 digit julian date. – MattS Mar 31 '16 at 17:01
  • 1
    Probably not helpful, but I would take the day number and use the Python datetime functions to turn it into a date, then you can easily select the month (including Leap years). date = datetime.datetime(2016, 1, 1) + datetime.timedelta(day-1) – Richard Morgan Mar 31 '16 at 17:05
2

Inefficient structure aside (you may want to use dictionaries instead of 12 month variables and 12 if statements), your day variable is a string, but you're comparing it against integers in your if statements.

Change day = jdate to day = int(jdate)

EDIT:

The else statement will print for everything prior to December; you should change all but the first if to elif.

Also, I tested the code, and it worked just fine; m1 was populated with the file. If it's printing out lstrasters correctly, then the code should work after you convert day to an integer.

I sense that the code you posted isn't exactly the code you're running. You don't import os, so what else is different? That's where the answer lies.

I've tested the following code:

import arcpy, os
from arcpy import sa
from arcpy import env
import glob

directory = r'C:\rasters'

lstrasters = glob.glob(directory + os.sep + "*.tif")
lstrasters.sort()
print lstrasters

m1 = [] #empty Jan list
m2 = [] #empty Feb list
m3 = []
m4 = []
m5 = []
m6 = []
m7 = []
m8 = []
m9 = []
m10 = []
m11 = []
m12 = []

for lstras in lstrasters:
    jdate = str(lstras[-7:-4])
    day = int(jdate)
    print day
    sa.Raster(lstras)
    if day in range(1,32):
        m1.append(lstras)
    elif day in range(32,60):
        m2.append(lstras)
    elif day in range(60,91):
        m3.append(lstras)
    elif day in range(91,121):
        m4.append(lstras)
    elif day in range(121,152):
        m5.append(lstras)
    elif day in range(152,182):
        m6.append(lstras)
    elif day in range(182,213):
        m7.append(lstras)
    elif day in range(213,244):
        m8.append(lstras)
    elif day in range(244,274):
        m9.append(lstras)
    elif day in range(274,305):
        m10.append(lstras)
    elif day in range(305,335):
        m11.append(lstras)
    elif day in range(335,366):
        m12.append(lstras)
    else:
        print "jdate is out of range"

print m1
print m2
print m3
print m4
print m5
print m6
print m7
print m8
print m9
print m10
print m11
print m12

...and this was the output:

['C:\\rasters\\ASPECT_001.tif', 'C:\\rasters\\DEM_132.tif', 'C:\\rasters\\HILLSHADE_487.tif', 'C:\\rasters\\SLOPE_PERCENT_362.tif']
1
132
487
jdate is out of range
362
['C:\\rasters\\ASPECT_001.tif']
[]
[]
[]
['C:\\rasters\\DEM_132.tif']
[]
[]
[]
[]
[]
[]
['C:\\rasters\\SLOPE_PERCENT_362.tif']
  • I changed it to day = int(jdate) and reran it but got the same empty lists. – MattS Mar 31 '16 at 16:52
  • Ok, that worked! I changed every statement to elif after the first if statement (m1) and then I got the rasters to populate each m1-m12 list. Thanks for your help! – MattS Mar 31 '16 at 17:34
1

As others have commented, this can be simplified quite a bit with dictionaries and the datetime module. This module will handle leap years for you (which, as I just learned, doesn't follow the "every four years" I always had thought).

import os, datetime, collections

rasters = ["lst2014189.tif","lst2014005.tif","lst2014352.tif","lst2014200.tif"]

ddict = collections.defaultdict(list)
for raster in rasters:
    name = os.path.splitext(raster)[0] # Use this instead of hardcoding -3
    # extract date info and convert to datetime
    # YYYYJJJ
    date = datetime.datetime.strptime(name[-7:], '%Y%j')
    # And convert back to month abbreviation
    month = date.strftime('%b') # %m if you want integer month representation
    # Append to ddict
    ddict[month].append(raster)


for item in ddict.items():
    print(item)

('Jan', ['lst2014005.tif'])
('Dec', ['lst2014352.tif'])
('Jul', ['lst2014189.tif', 'lst2014200.tif'])

So instead of all your variables for each month, you'd just use ddict['month']. If your folder contains multiple years, it's a simple change to nest dictionaries so that you can use, say, ddict[year]['month'].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.