Montpellier Sabbatical II

Between July 2009 and July 2010, I and two little kids rode Ruth's sabbatical coattails to Montpellier in the south of France. This was my first blog post on arrival: https://sgillies.net/2009/07/06/nous-sommes-arrivs-montpellier.html. Seven years later, we're headed back to the Hérault (34)! I'm super excited and a bit anxious, the next few months are going to be a bit crazy.

https://c1.staticflickr.com/5/4124/4831955788_39edb3e93d_b_d.jpg

Moving to France for a year involves a lot of smaller tasks. Some of these we have already ticked off:

  • Ruth is going to be hosted by CGBP (Centre de Biologie pour la Gestion des Populations – Population Biology) again. Great people, great facility.

  • I've got the +1 and support from my team at Mapbox.

  • We've found and made a deposit on a house in Montpellier. The proprietaires are university profs and very helpful.

  • We have a date at the French Consulate General in Los Angeles to get long stay visas. This is a new twist, last time we took care of this in France.

  • We've tuned up our French language skills. I expect our kids are going to impress their teachers.

Ruth found a rental house in the country that was just 5 mins from her lab via VTT (mountain bike) singletrack (!!) but we decided to go with a house in a more central Montpellier neighborhood.

There is yet much to do:

  • Find renters for our house in Fort Collins.

  • Pack and ship essentials across the ocean (our 7 and 10 year-olds have much greater requirements than last time), and store other stuff locally.

  • Learn how to transport a dog to France.

  • Find some late summer or fall trail running races in Europe to replace the Black Squirrel race I'd otherwise run here in September.

  • Plan our upcoming vacations. the French do this well in advance and you run the risk of finding everything is booked if you wait till the last minute.

Fort Collins and Montpellier have a lot in common. Both are fast-growing university and government centers with sunny climates and good access to outdoor recreation. But there are things Montpellier has that Fort Collins does not:

  • Year-round farmers markets. Local strawberries in April (now!) with cherries and other fruit not far behind.

  • Excellent local wine regions like La Clape and Pic Saint-Loup.

  • The Lucques variety of olive.

  • Bakeries. The Crêperie here in the Fort is good, but there are many places in Montpellier making baguettes just as well. And the sourdough (levain) baking in Montpellier is much better.

  • Merguez sausage.

  • Fresh fish and oysters.

  • A short drive to the beach.

  • TGV connections to Paris and Barcelona. Just 3 hours to each.

  • Historical public places like Place de la Comédie and the Promenade du Peyrou.

It's not all milk and honey, however. Montpellier also has hellish traffic (I don't expect it's any better seven years later), high unemployment, ghettos of poorly integrated immigrants, and a large homeless population. It's grittier than Fort Collins, more troubled, and in that sense more real.

I'll write more about the move when summer arrives.

Rasterio 0.34

Last fall Even Rouault announced that GDAL 2.1 would have a new Amazon S3 virtual file system. Extending GDAL's capability to make HTTP byte range requests to AWS's HTTPS + XML S3 API, Even has made it possible to efficiently access partial content of S3 objects using certain formats like GeoTIFF. In other words, metadata of a GeoTIFF on S3 or overviews stored as sub-images can be accessed without retrieving the bulk of its image data. Génial!

With help from Even, Rob Emanuele, and Matt Perry, Rasterio 0.34 has a handy abstraction for this feature. Rasterio uses s3:// URIs instead of GDAL's /vsis3/ paths because URIs are how we identify resources on the web and because this is the URI scheme – if unregistered – used by the AWS Command Line Interface. The same URIs you use with the AWS CLI

$ aws s3 ls s3://landsat-pds/L8/139/045/LC81390452014295LGN00/LC81390452014295LGN00_B1.TIF
2015-03-14 17:20:01   51099231 LC81390452014295LGN00_B1.TIF
2015-03-14 17:20:30    6626356 LC81390452014295LGN00_B1.TIF.ovr

can also be used with Rasterio:

$ rio info s3://landsat-pds/L8/139/045/LC81390452014295LGN00/LC81390452014295LGN00_B1.TIF --indent 2
{
  "nodata": null,
  "dtype": "uint16",
  "crs": "EPSG:32645",
  "bounds": [
    381885.0,
    2279085.0,
    610515.0,
    2512815.0
  ],
  "count": 1,
  "blockxsize": 512,
  "driver": "GTiff",
  "transform": [
    30.0,
    0.0,
    381885.0,
    0.0,
    -30.0,
    2512815.0
  ],
  "blockysize": 512,
  "tiled": true,
  "lnglat": [
    86.96327090815723,
    21.666821827007748
  ],
  "shape": [
    7791,
    7621
  ],
  "compress": "deflate",
  "res": [
    30.0,
    30.0
  ],
  "width": 7621,
  "height": 7791,
  "interleave": "band"
}

Rasterio gets its credentials in the same manner as the AWS CLI (see Configuring the AWS Command Line Interface). If you're already using the AWS CLI no extra configuration is needed to start using Rasterio on S3 raster datasets.

A close read of the GDAL debug logs shows that only 16384 bytes of this 50MB TIFF are fetched in order to get the metadata printed above. That's an efficiency of 3000:1.

The S3 virtual filesystem is only available in Rasterio if you have a GDAL library version >= 2.1.0dev. The macosx wheels for Rasterio 0.34 on PyPI contain GDAL version 2.1.0dev and are probably the easiest way to try this new feature.

Share and enjoy!

Moab from Landsat 8

I've still got the Colorado Plateau on my mind and spent some time yesterday dressing up the image below for a Mapbox Instagram post.

https://c2.staticflickr.com/2/1548/25444509183_637f031af3_b_d.jpg

2016-02-28 was a clear day in Southeastern Utah

I used Development Seed's excellent landsat-util utility to find and download the source imagery, rio stack (from Rasterio) to combine individual bands into an RGB TIFF, rio clip to extract a smaller region, rio convert to scale and reformat the 16-bits per band TIFF into a 8-bit per band PNG, and Imagemagick for sigmoidal constrast enhancement and alpha adjustment.

All of the above was done using Python 3.5.1, which is now an option for landsat-util 0.13.0.

Spring Break in Arches and Canyonlands

School was out last week, Poudre Schools and Colorado State, and my family and I took a Spring Break trip to hike in Arches and Canyonlands National Parks. We stayed 4 nights in Moab, Utah, the biggest town in Southeastern Utah and 415 miles from Fort Collins. It's a long, but scenic drive, and once we got west of Vail Pass the road was clear of snow and it was all smooth sailing down I-70 to Crescent Junction and then down US-191 to Moab.

I grew up in Utah, have family roots in Southern Utah, visited Arches and/or Canyonlands annually in the 70s and 80s, but haven't been to Moab in a long time. 1992 may have been my last visit. The town has changed a lot on the surface and probably a little bit underneath. Moab's espresso machine population has increased about twentyfold and you can walk out of a craft brewery with a 4-pack of full strength IPA. While grabbing some picnic food in the City Market, I heard Built to Spill's The Plan as shopping music. It's weird. Moab panders shamelessly to the forty-something weekend warrior like me.

On our first day, we drove into Arches N.P. As you see in the photo below, the dramatic features of Arches are largely found in the brick red Entrada Sandstone that sits atop the buff colored Navajo Sandstone.

https://upload.wikimedia.org/wikipedia/commons/thumb/a/a3/The_Three_Gossips_at_Arches_National_Park.jpg/1200px-The_Three_Gossips_at_Arches_National_Park.jpg

By Sanjay Acharya - Own work, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=8101229

There's a particular angle when you're driving back towards the park's visitors center and very close to these titanic figures where one appears to be whispering in the ear of another. Something more serious than mere gossip is going on.

My kids loved scrambling on the park's characteristic joints and fins. These are created by collapse of a deeply buried salt deposit, the sandstone fracturing as its foundation warps.

https://c2.staticflickr.com/2/1540/25332791273_eefb5471a9_b_d.jpg

On the Devil's Garden Trail in Arches N.P.

Erosion of the fins can produce free standing rock arches. The park touts over 2000 of them. These arches are ephemeral in geologic time; the iconic Wall Arch (in the same Devil's Garden area) collapsed on August 4, 2008. Landscape Arch, the second longest natural arch in the world, is ever more delicate. According to Wikipedia (no source that I can find) 43 arches are known to have collapsed since 1977.

https://c2.staticflickr.com/2/1639/25660076720_8419dc99c5_b_d.jpg

The Double O Arch

We weren't the only family on the trail that day. We weren't even the only family from Fort Collins, and bumped into people we know from school and soccer. On returning home our oldest learned that her class's student teacher had been to Moab before us, on the earlier end of Spring Break.

Later that same day I did a 7 mile evening trail run from the BLM's Hidden Valley trailhead up and over the rim southwest of Moab, stopping to check out a few panels of rock art and admire the problems along the Moab Rim jeep trail.

https://c2.staticflickr.com/2/1460/25660096300_d3915c6676_b_d.jpg

Trail sign between Hidden Valley and Moab Rim Trail

There was a point in this run where I realized that I was poorly prepared for any bad turn of events. I'd brought no water, no food, no map, no jacket, no light, and had no internet. I was all alone on the rim, the sun was going down, and the connection between the Hidden Valley and Moab Rim Trails wasn't as obvious as I had expected. Visions of descending from the rim in the dark haunted me as I lost the trail briefly on a slickrock dome, but I managed to find my way through to the jeep trail and its companion hiking trail, named "Stairmaster." Ruth and our kids picked me up at the finish, 30 minutes later than planned, and we went back into town for dinner.

https://c2.staticflickr.com/2/1546/25331941443_4e07a5218e_b_d.jpg

Dome above Hidden Valley

We spent one day hiking in Canyonlands N.P., which was practically empty compared to Arches. The highlights of this day for me were the clear views of the nearby La Sal and more distant Henry Mountain ranges afforded from the Island in the Sky district of the park.

https://c2.staticflickr.com/2/1686/25934818746_dfb76096cd_b_d.jpg

Mesa Arch and La Sal Mountains

On our last full day in the area we went back to Arches and Ruth and I traded turns at long runs in the backcountry, starting from Balanced Rock.

https://c2.staticflickr.com/2/1644/25960708835_61f538f563_b_d.jpg

Arches backcountry signage

I ran out and back, 14 miles in all, this time with ample water, food, jacket, and map. Just in case.

https://c2.staticflickr.com/2/1479/25960727405_490e772e6a_b_d.jpg

Whale Rock and the Henry Mountains in the distance

I saw only two other people during my run, a couple touring in their Jeep Cherokee. After they confirmed that I wasn't stranded, we headed our separate ways.

https://c2.staticflickr.com/2/1594/25839919082_6da924fdfb_b_d.jpg

La Sal Mountains and the Windows

I've been on a mission to turn my kids into desert rats and I think I've finally succeeded. Every one of us is looking forward to coming back sooner rather than later.

Our admission to the parks was free thanks to Every Kid in a Park, a new White House initiative. Our oldest is in 4th grade and she and her peers can take family and friends to U.S. National Parks through August of 2016.

https://raw.githubusercontent.com/18F/ekip-api/master/ekip/everykid/static/img/nav-logo.png

A cool thing about the initiative's website is that the source is on GitHub: https://github.com/18F/ekip-api. Good job, 18F!

https://upload.wikimedia.org/wikipedia/commons/1/1d/US-NationalParkService-Logo.svg

National Park Service Logo since 1951

Running in Winter

I'm registered for this year's Colorado Marathon on May 1. It starts about 18 miles up the Poudre Canyon – which will be closed to cars during the event! – and finishes along the Poudre River Trail. This will be my first Marathon.

After taking it easy in October, November, and December. I started an 18 week training program after Christmas. I ran 90 miles in January and 108 in February. I expect to run more miles this March than I've ever run in a single month: over 130.

I'm prone to some wintertime depression and running has been helping me in a bunch of ways. The exercise is good, obviously, and making measurable progress on my accumulated miles and pace is great for my morale. Having a mission has helped me hop out of bed and get outside for daylight and fresh air that I might miss if I went directly to work on my computer (I work remotely, if you remember). I haven't been quantifying my mood this season, but I think it's been relatively good. I've been bringing my dog along on most of my less-than-race-pace runs, as far as 12 miles, and it's been great for her mood, too.

Temperatures have been pretty mild, but we've had plenty of snow. More than ever, I appreciate access to the Parks Department's well-maintained trails. While streets and sidewalks were in a hopeless state, I could always get to the Spring Creek, Mason, Fossil Creek, and Poudre Trails for smooth sailing.

https://c2.staticflickr.com/2/1446/24862154863_2bd365a6a8_b_d.jpg

Poudre River and Trail

https://c2.staticflickr.com/2/1646/25370389592_a851b9f059_b_d.jpg

Fossil Creek Trail

I happened to be in Winter Park on a weekend where I was scheduled to do a long, 14 mile run. I ran from the neighborhood in Fraser uphill from the Safeway, along the Fraser River Trail next to US-40 into the town of Winter Park, then along the wooded and snow-covered stretch of the trail into the Winter Park ski area. I met my family, who were just arriving at the lifts, and then reversed course. I went at a much slower pace than I do at home, so even at 8500-9000 feet, I felt comfortable. The final hill was a killer.

https://c2.staticflickr.com/2/1556/24858266274_383dabb840_b_d.jpg

Fraser River, Winter Park, and Berthoud Pass

https://c2.staticflickr.com/2/1464/25370380092_a3e137f485_b_d.jpg

West end of the Moffat Tunnel

Now Winter seems to be over. Snow is long gone, the foothill trails are drying, and buds are beginning to burst on the trees. I'm looking forward to morning runs with no hat and gloves!

Building I-Ds and RFCs with CircleCI

In the IETF GeoJSON WG we're using the technique described in RFC 7328 -- Writing I-Ds and RFCs Using Pandoc and a Bit of XML to write our drafts and GitHub to collaborate on the Markdown sources. I've configured CircleCI to build HTML, nroff, text, and XML editions of the draft on each push and pull request to catch issues that break the draft building toolchain. I'm not fluent with RFC editor XML and mess up the tagging regularly, so this is helping the WG quite a bit.

Recently I woke up to the possibilities in saving the text and HTML editions as CircleCI build artifacts. Here's the circle.yml file from https://github.com/geojson/draft-geojson:

machine:
  python:
    version: 2.7.10

dependencies:
  pre:
    - sudo apt-get update; sudo apt-get install pandoc
    - pip install -U pip
    - pip install xml2rfc

test:
  override:
    - make
    - head draft.txt

general:
  artifacts:
    - draft.txt
    - draft.html

Under the Artifacts tab on a CircleCI build page, there's a browseable folder hierarchy that exposes links to draft.html and draft.txt.

I should have done this sooner! I may look into including some of the IETF tools like idnits and idspell.

IETF GeoJSON

Having busted up my technical/administrative blogjam, I'm going to try to catch up on the news from my little corner of the world. The new IETF GeoJSON working group that I've been incubating finally hatched on October 1. The chairs are Martin Thomson and Erik Wilde and I'm playing the role of lead editor. All but one of the original format spec authors are participating in the working group along others from the original email list and a bunch of IETF folks. We're going to ship two documents: a GeoJSON format specification (with clarifications and extension guidance) and a document describing a format for a streamable sequence of GeoJSON texts (as I've sketched out in this blog previously).

The IETF GeoJSON WG will operate out of the existing https://github.com/geojson/draft-geojson repo and use an IETF GeoJSON mailing list https://www.ietf.org/mailman/listinfo/geojson for discussion and announcements. See https://github.com/geojson/draft-geojson/blob/master/CONTRIBUTING.md for all the details about contributing. The WG's draft is https://datatracker.ietf.org/doc/draft-ietf-geojson/ and replaces the old https://datatracker.ietf.org/doc/draft-butler-geojson/ draft that we've been iterating on for a year or so. This is to say that the IETF GeoJSON WG has adopted the draft of the independent GeoJSON working group and that the independent GeoJSON working group has become the IETF GeoJSON WG.

To get to the next revision of draft-ietf-geojson, I'm going through the outstanding issues in the tracker, summarizing them to the discussion list, and trying to reach consensus on whether to add text to the spec, remove text from the spec, or leave it alone. Some of these are more contentious than others, such as if and how GeoJSON should be extended. So far we have consensus that there is extensibility, but no consensus that there is a capital E Extension Framework.

If you've ever felt that the GeoJSON specification wasn't clear enough on something or is out of step with recent technological advances, this is the time to jump in and help improve it.

Migration of my blog

A while back I switched my blog from a database-backed dynamic site to static HTML generated by Sphinx and Tinkerer. This weekend I finished migrating eight years of old posts (with their comments) to the new blog. And I configured my new blog and home page to support HTTPS. Hello, 2015.

You may, when visiting old posts, experience browser warnings because of embedded HTTP resources. Images mainly, but also the odd script here and there. I have also not yet implemented the redirect rules that will get you from old style number/slug URLs to the new YYYY/MM/DD/slug URLs, though I have mapped them all out. Please bear with me, I'll address these issues soon.

Doing this lets me retire my last dedicated server. My blog now runs on a very cheap ($5 per month) virtual server provisioned (Nginx, SSL certs and keys, the works) using Ansible. I build my blog HTML on my laptop and rsync it with the server also using Ansible.

I'm pretty sure this blog migration is the final chapter of my Zope story. The following is very likely my final Zope external method, ever.

import json


def dumper(context):
    """Dump Python blog posts to JSON"""
    for result in context.searchResults(
            meta_type='COREBlog Entry', sort_on='created',
            sort_order='descending'):
        post = result.getObject()

        doc = {}
        doc['id'] = post.id
        doc['slug'] = post.entry_slug()
        doc['title'] = post.title_or_id()
        doc['body'] = post.body
        doc['categories'] = post.categories()
        doc['published'] = post.published()
        doc['html'] = (post.format == 2)

        coms = []
        for comment in post.comment_list():
            com = {}
            com['title'] = comment.title
            com['author'] = comment.author
            com['url'] = comment.url
            com['body'] = comment.body
            coms.append(com)
        doc['comments'] = coms

        date = post.published().split('T')[0]
        date = date.replace('-', '')

        outfilename = '/tmp/blog/{0}-{1}-{2}.json'.format(
            date, post.id, post.entry_slug())

        with open(outfilename, 'w') as f:
            json.dump(doc, f, indent=2)

Black Squirrel Half Marathon

Saturday was the 3rd running of the Black Squirrel Half Marathon. It's a roughly triangular route up and over the top of Lory State Park and back along the East Valley Trail.

I finished 97th out of 312 in 2:23:24. This is 7 minutes slower than my trail half on Taylor Mountain outside Issaquah, WA in June. I had a cold and hadn't slept well in a few days so wasn't at my best. Between the last two aid stations I was going backwards, but rallied enough over the last 2.5 miles to move up 3 places. Although I didn't do as well as I'd hoped, I enjoyed the race and finished with nothing left in my tank and no regrets. High points: hanging out with my friend and former ultimate teammate Jeanne (who finished 3rd in the womens masters category), not falling on any rocks, shady pine groves on the West Ridge Trail, and a great view of Longs Peak from the top.

Ruth battled back from a slow start to finish in 2:35:57. She said she passed about 50 runners on the singletrack going up and that the intermittent speed bursts and lack of consistent pace was exhausting. Aaron Anderson, who works in a lab down the hall from Ruth, was the winner in 1:30:02. This was 8 minutes faster than the winning time in Issaquah!

It's humbling to be a mere mortal among actually elite athletes, but it's also completely okay. See also Jacob Kaplan-Moss's great Pycon keynote on being average in running and programming.

Here's a photo of the run rising over the plains to the east before the start. I'm not a morning person at all, but I love the light and stillness of dawn.

https://farm6.staticflickr.com/5726/21198158526_d28c213cff_b_d.jpg

Lory State Park at dawn