So far this winter we’ve gotten only 4.1 inches of snow, well below the normal 19.7 inches, and there is only 2 inches of snow on the ground. At this point last year we had 8 inches and I’d been biking and skiing on the trail to work for two weeks. In his North Pacific Temperature Update blog post, Richard James mentions that winters like this one, with a combined strongly positive Pacific Decadal Oscillation phase and strongly negative North Pacific Mode phase tend to be a “distinctly dry” pattern for interior Alaska. I don’t pretend to understand these large scale climate patterns, but I thought it would be interesting to look at snowfall and snow depth in years with very little mid-November snow. In other years like this one do we eventually get enough snow that the trails fill in and we can fully participate in winter sports like skiing, dog mushing, and fat biking?
We will use daily data from the Global Historical Climate Data set for the Fairbanks International Airport station. Data prior to 1950 is excluded because of poor quality snowfall and snow depth data and because there’s a good chance that our climate has changed since then and patterns from that era aren’t a good model for the current climate in Alaska.
We will look at both snow depth and the cumulative winter snowfall.
The following tables show the ten years with the lowest cumulative snowfall and snow depth values from 1950 to the present on November 18th.
|Year||Cumulative Snowfall (inches)|
|Year||Snow depth (inches)|
2016 has the second-lowest cumulative snowfall behind 1953 and is tied for second with 2014 for snow depth with 1953, 1954 and 1962 all having only 1 inch of snow on November 18th.
It also seems like recent years appear in these tables more frequently than would be expected. Grouping by decade and averaging cumulative snowfall and snow depth yields the pattern in the chart below. The error bars (not shown) are fairly large, so the differences between decades aren’t likely to be statistically significant, but there is a pattern of lower snowfall amounts in recent decades.
Now let’s see what happened in those years with low snowfall and snow depth values in mid-November starting with cumulative snowfall. The following plot (and the subsequent snow depth plot) shows the data for the low-value years (and one very high snowfall year—1990), with each year’s data as a separate line. The smooth dark cyan line through the middle of each plot is the smoothed line through the values for all years; a sort of “average” snowfall and snow depth curve.
In all four mid-November low-snowfall years, the cumulative snowfall values remain below average throughout the winter, but snow did continue to fall as the season went on. Even the lowest winter year here, 2006–2007, still ended the winter with 15 inches of snow on the groud.
The following plot shows snow depth for the four years with the lowest snow depth on November 18th. The data is formatted the same as in the previous plot except we’ve jittered the values slightly to make the plot easier to read.
The pattern here is similar, but the snow depths get much closer to the average values. Snow depth for all four low snow years remain low throughout November, but start rising in December, dramatically in 1954 and 2014.
One of the highest snowfall years between 1950 and 2016 was 1990–1991 (shown on both plots). An impressive 32.8 inches of snow fell in eight days between December 21st and December 28th, accounting for the sharp increase in cumulative snowfall and snow depth shown on both plots. There are five years in the record where the cumulative total for the entire winter was lower than these eight days in 1990.
Despite the lack of snow on the ground to this point in the year, the record shows that we are still likely to get enough snow to fill in the trails. We may need to wait until mid to late December, but it’s even possible we’ll eventually reach the long term average depth before spring.
Here’s the R code used to generate the statistics, tables and plots from this post:
library(tidyverse) library(lubridate) library(scales) library(knitr) noaa <- src_postgres(host="localhost", dbname="noaa") snow <- tbl(noaa, build_sql( "WITH wdoy_data AS ( SELECT dte, dte - interval '120 days' as wdte, tmin_c, tmax_c, (tmin_c+tmax_c)/2.0 AS tavg_c, prcp_mm, snow_mm, snwd_mm FROM ghcnd_pivot WHERE station_name = 'FAIRBANKS INTL AP' AND dte > '1950-09-01') SELECT dte, date_part('year', wdte) AS wyear, date_part('doy', wdte) AS wdoy, to_char(dte, 'Mon DD') AS mmdd, tmin_c, tmax_c, tavg_c, prcp_mm, snow_mm, snwd_mm FROM wdoy_data")) %>% mutate(wyear=as.integer(wyear), wdoy=as.integer(wdoy), snwd_mm=as.integer(snwd_mm)) %>% select(dte, wyear, wdoy, mmdd, tmin_c, tmax_c, tavg_c, prcp_mm, snow_mm, snwd_mm) %>% collect() write_csv(snow, "pafa_data_with_wyear_post_1950.csv") save(snow, file="pafa_data_with_wyear_post_1950.rdata") cum_snow <- snow %>% mutate(snow_na=ifelse(is.na(snow_mm),1,0), snow_mm=ifelse(is.na(snow_mm),0,snow_mm)) %>% group_by(wyear) %>% mutate(snow_mm_cum=cumsum(snow_mm), snow_na=cumsum(snow_na)) %>% ungroup() %>% mutate(snow_in_cum=round(snow_mm_cum/25.4, 1), snwd_in=round(snwd_mm/25.4, 0)) nov_18_snow <- cum_snow %>% filter(mmdd=='Nov 18') %>% select(wyear, snow_in_cum, snwd_in) %>% arrange(snow_in_cum) decadal_avg <- nov_18_snow %>% mutate(decade=as.integer(wyear/10)*10) %>% group_by(decade) %>% summarize(`Snow depth`=mean(snwd_in), snwd_sd=sd(snwd_in), `Cumulative Snowfall`=mean(snow_in_cum), snow_cum_sd=sd(snow_in_cum)) decadal_averages <- ggplot(decadal_avg %>% gather(variable, value, -decade) %>% filter(variable %in% c("Cumulative Snowfall", "Snow depth")), aes(x=as.factor(decade), y=value, fill=variable)) + theme_bw() + geom_bar(stat="identity", position="dodge") + scale_x_discrete(name="Decade", breaks=c(1950, 1960, 1970, 1980, 1990, 2000, 2010)) + scale_y_continuous(name="Inches", breaks=pretty_breaks(n=10)) + scale_fill_discrete(name="Measurement") print(decadal_averages) date_x_scale <- cum_snow %>% filter(grepl(' (01|15)', mmdd), wyear=='1994') %>% select(wdoy, mmdd) cumulative_snowfall <- ggplot(cum_snow %>% filter(wyear %in% c(1953, 1954, 2014, 2006, 1990), wdoy>183, wdoy<320), aes(x=wdoy, y=snow_in_cum, colour=as.factor(wyear))) + theme_bw() + geom_smooth(data=cum_snow %>% filter(wdoy>183, wdoy<320), aes(x=wdoy, y=snow_in_cum), size=0.5, colour="darkcyan", inherit.aes=FALSE, se=FALSE) + geom_line(position="jitter") + scale_x_continuous(name="", breaks=date_x_scale$wdoy, labels=date_x_scale$mmdd) + scale_y_continuous(name="Cumulative snowfall (in)", breaks=pretty_breaks(n=10)) + scale_color_discrete(name="Winter year") print(cumulative_snowfall) snow_depth <- ggplot(cum_snow %>% filter(wyear %in% c(1953, 1954, 1962, 2014, 1990), wdoy>183, wdoy<320), aes(x=wdoy, y=snwd_in, colour=as.factor(wyear))) + theme_bw() + geom_smooth(data=cum_snow %>% filter(wdoy>183, wdoy<320), aes(x=wdoy, y=snwd_in), size=0.5, colour="darkcyan", inherit.aes=FALSE, se=FALSE) + geom_line(position="jitter") + scale_x_continuous(name="", breaks=date_x_scale$wdoy, labels=date_x_scale$mmdd) + scale_y_continuous(name="Snow Depth (in)", breaks=pretty_breaks(n=10)) + scale_color_discrete(name="Winter year") print(snow_depth)
It’s been almost a month since I last discussed the first true snowfall date (when the snow that falls stays on the ground for the entire winter) in Fairbanks, and we’re still without snow on the ground. It hasn’t been that cold yet, but the average temperature is enough below freezing that the local ponds have started freezing. Without snow, there’s a lot of ice skating going on around town. I’m hoping to head out this weekend and do some skating on the pond in the photo above. Still, most folks in Fairbanks are hoping for snow.
Since my last post, I’ve gotten access to data from the National Climate Data Center, and have been working on getting it all processed into a database. I’ve worked out a procedure for processing the daily COOP data, which means I can repeat my earlier snow depth analysis with a longer (and more consistent) data set. The following figure shows the same basic analysis as in my previous post, but now I’ve got data from 1948 to 2008.
The latest date for the first true snowfall was November 11th, 1962, and we’re almost three weeks away from that date. But we’re also on the right side of the distribution—the mean (and median) date is October 14th, and we’re 9 days past that with no significant snow in the forecast. I’ve also marked the earliest (September 13th, 1992) and latest (November 1st, 1997) first snowfall dates in recent history. 1992 was the year the snow fell while the leaves were still on the trees, causing major power outages and a lot of damage. I think 1997 was the year that we didn’t get much snow at all, which caused a lot of problems for water and septic lines buried in the ground. A deep snowpack provides a good insulating layer that keeps buried water lines from freezing and in 1997 a lot of things froze.
This is also the time of the year when some of the winter birds start making themselves less scarce. We saw our first Pine Grosbeaks of the year, three days later than last year’s first observation, a Northern Goshawk flew over a couple weeks ago, and we got some great views of this Great Horned Owl on Saturday. Andrea took some spectacular photos with her digital camera, and I experimented with my iPhone and the scope we bought in Homer this year. It’s quite a challenge to get the tiny iPhone lens properly oriented with the eyepiece image in the scope, but the photos are pretty impressive when you get it all set up. Even a pretty wimpy camera becomes powerful when looking through a nice scope.
Winter is on it’s way, just a bit late this year. I’ve been taking advantage by riding my bike to work fairly often. Earlier in the week I replaced my normal tires with carbide-studded tires, so I’ll be ready when the ice and snow finally comes.
On Wednesday I reported the results of my analysis examining the average date of first snow recorded at the Fairbanks Airport weather station. It was based on the snow_flag boolean field in the ISD database. In that post I mentioned that examining snow depth data might show the date on which permanent snow (snow that lasts all winter) first falls in Fairbanks. I’m calling this the first “true” snowfall of the season.
For this analysis I looked at the snow depth field in the ISD database for the Fairbanks station. The data was present for the years between 1973 and 1999, but isn’t in the database before that date. I’m not sure why it’s not in there after 1999, but luckily I’ve been collecting and archiving the data in the Fairbanks Daily Climate Summary (which includes a snow depth measurement) since late 2000. Combining those two data sets, I’ve got data for 27 years.
The SQL query I came up with to get the data from the data sets is a good estimate of what we’re interested in, but isn’t perfect because it only finds the date of first snow that lasts at least a week. In a place like Fairbanks where the turn to winter is so rapid and so dependent on the high albedo of snow cover, I think it’s close enough to the truth. Unfortunately, the query is brutally slow because it involves six (!) inner self-joins. The idea is to join the table containing snow depth data against itself, incrementing the date by one day at each join. The result set before the WHERE statement is the data for each date, plus the data for the six days following that date. The WHERE clause requires that snow depth on all those seven dates is above zero. This large query is a subquery of the main query which selects the earliest date found in each year.
There must be a better way to deal with conditions like this where we’re interested in the consecutive nature of the phenomenon, but I couldn’t figure out any other way to handle it in SQL, so here it is:
SELECT year, min(date) FROM ( SELECT extract(year from a.dt) AS year, to_char(extract(month from a.dt), '00') || '-' || ltrim(to_char(extract(day from a.dt), '00')) AS date FROM isd_daily AS a INNER JOIN isd_daily AS b ON a.isd_id=b.isd_id AND a.dt=b.dt - interval '1 day' INNER JOIN isd_daily AS c ON a.isd_id=c.isd_id AND a.dt=c.dt - interval '2 days' INNER JOIN isd_daily AS d ON a.isd_id=d.isd_id AND a.dt=d.dt - interval '3 day' INNER JOIN isd_daily AS e ON a.isd_id=e.isd_id AND a.dt=e.dt - interval '4 day' INNER JOIN isd_daily AS f ON a.isd_id=f.isd_id AND a.dt=f.dt - interval '5 day' INNER JOIN isd_daily AS g ON a.isd_id=g.isd_id AND a.dt=g.dt - interval '6 day' WHERE a.isd_id = '702610-26411' AND a.snow_depth > 0 AND b.snow_depth > 0 AND c.snow_depth > 0 AND d.snow_depth > 0 AND e.snow_depth > 0 AND f.snow_depth > 0 AND g.snow_depth > 0 AND extract(month from a.dt) > 7 ) AS snow_depth_conseq GROUP BY year ORDER BY year;
See what I mean? It’s pretty ugly. Running the result through the same R script as in my previous snowfall post yields this plot:
Between 1973 and 2008 we’ve gotten snow lasting the whole winter starting as early as September 12th (that was the infamous 1992), and as late as the first of November (1976). The median date is October 13th, which matches my impression. Now that the leaves have largely fallen off the trees, I’m hoping we get our first true snowfall on the early end of the distribution. We’ve still got a few things to take care of (a couple new dog houses, insulating the repaired septic line, etc.), but once those are done, I’m ready for the Creek to freeze and snow to blanket the trails.
We got our first dusting of snow last night. It stuck around until after noon, allowing me to take the photo on the right when I went for a walk with Nika around the peat bog. You can really tell where the permafrost is by the thick layer of insulating moss that keeps the ground frozen, and is keeping the snow from melting in the photo.
Every year when the first snow falls it seems like it’s earlier than the last, and there’s usually some discussion at the office about how short the summer turned out to be. The early snows of 1992 that knocked out power for days all over town are also normally mentioned. I decided to look and see if I had some data that could place this year’s first snowfall in a historical context.
One of the few free† long-term weather datasets that’s available from the National Climate Data Center is the Integrated Surface Dataset (ISD), which contains daily weather observations for more than 20,000 stations. The Fairbanks Airport station has been in operation for more than 100 years, but it moved in 1946, so I only used data from 1946–2008. In addition to a series of numerical observations (minimum and maximum temperature, pressure, wind speed, etc.), the dataset contains several fields used to indicate whether a particular phenomenon was observed during that day. One of them, snow_flag, is defined as: “True indicates there was a report of snow or ice pellets during the day.”
That’s perfect. Snow depth is another parameter I considered, but this data wasn’t collected until the mid-70s, and it doesn’t really help us answer the question because most of the time the first snowfall of the year doesn’t last long enough to be recorded as snow on the ground.
Here’s the SQL query to find the earliest snowfall date for each year for the Fairbanks Airport station:
SELECT year, min(date) FROM ( SELECT extract(year from dt) AS year, to_char(extract(month from dt), '00') || '-' || ltrim(to_char(extract(day from dt), '00')) AS date, snow_flag FROM isd_daily WHERE isd_id = '702610-26411' AND extract(month from dt) > 7 AND snow_flag = 't' ) AS snow_flag_sub GROUP BY year ORDER BY year;
Mix in a little R:
fs <- read.table("first_snow_mm-dd", header=TRUE, row.names=1) fs$date<-as.Date(fs$date, "%m-%d") png("first_snow_mm-dd.png", height=500, width=500, units="px", pointsize=12) hist(fs$date, breaks="weeks", labels=FALSE, xlab="Date of first snowfall", main="First snowfall reported, Fairbanks Airport (PAFA) station", plot=TRUE, freq=TRUE, ylim=c(0, 20), col="gray60") text(as.Date("2009-09-23"), 19, "⇦ 2009", srt=90, col="darkred") dev.off()
And you get this plot:
You can see from the plot that the first snowfall comes somewhere between August 3rd and October 26th, with the week of September 21st being the most common. So we’re right on schedule this year.
Another analysis that I’ve been meaning to do is to find the average date when the snow that falls lasts the entire winter. Since I’ve been in Fairbanks, my estimate of this date is the second week of October, but I’ve never actually looked it up to see if that’s true or not. Unfortunately, this requires good snow depth data, and the ISD dataset doesn’t have snow depth for Fairbanks prior to 1975. It’s also a bit more complicated than looking for the earliest snow_flag = 't' because you need to examine future rows to know if the snow depth observation you’re examining lasted more than a few days.
†Why isn’t all the data collected by the Weather Service freely available? Public money was used to collect, analyze, and archive it, so I think it should be made available to the public that paid for it.