pictures

Critters of Yellowstone

After spending a few days in south-western Montana for the Fools Gold 50 Miler (which was rerouted into a 50k mid-race when race management found that Friday night’s snowfall (in August — yes, I know!) made the high ridges impassable, or at least unsafe), Martha and I headed to Yellowstone for a few days of critter tracking. I tend to be a light packer, so I don’t usually travel with the “good” camera. But Yellowstone seemed worthy of an exception. By the time I had crammed my luggage with the 7D body, the 70-200mm f/2.4 lens, the 2x lens extender, and a wide lens, camera gear probably constituted a third of the mass of my bag.

The wide lens ended up being almost entirely unused. Although Yellowstone has some amazing landscapes, our trip motto became, “BOO geology, YAY biology!” We were much more interested in hiking on lightly used trails in search of some small sparrow we hadn’t yet seen, rather than join the hoards of tourists gathering to gaze at geysers. Eventually, despite Martha’s initial desire to see bears, we grew weary of our fellow park visitors who were only interested in large game — bears, wolves, and bison. In a pond by the side of a road, Martha and I were watching a white pelican scoop up fish, surrounded by buffleheads, when a pair of sandhill cranes came in for a landing on the opposite shore. We marveled at the scene, when a car pulled up.

“What is it?” they asked. We explained what we were observing. “Oh,” they responded in disappointment, “we want to see wolves.” Then they drove off.

We spent some time driving, looking for roadside attraction, as is the practice at Yellowstone. But we spent much more time hiking on trails where we saw few people. We walked slowly, trying to spot every bird or small mammal that rustled a leaf, or made a barely audible peep on the trail. And like hunters “bagging” game, we were getting photos as prizes of the critters we encountered.

The photo inventory of our animal sightings not only had the benefit of providing a record of the trip. It also allowed after-the-fact consultation with our go-to bird expert, Martha’s brother, Fred. While Martha was able to identify about 80% of the birds we saw, the obscure, the western, and the juveniles (which often have entirely different coloration from the adults) occasionally eluded her. (I, on the other hand, have the a level of expertise that only allows me to call out, “BIRD!” upon seeing some vaguely bird-shaped creature.)

In whittling down the pictures to a set small enough that it might have interest for casual viewers, I briefly considered creating a gallery consisting of all pictures I took of animals looking directly at the camera. While I could have put together a fair sized gallery of those pictures, I decided that that would force me to exclude higher quality images for lower quality images in order to meet an arbitrarily imposed criterion. Instead, I picked a collection of favorites that provides a representative sampling of what we saw. (Pictures are clickable for larger versions.)

blerg

Osprey in Flight

Early on the first day, while driving down a narrow road by a stream, Martha asked me to stop. I pulled into the next pull-off (which are abundant in Yellowstone for exactly this reason). We walked back up the shoulder of the road to find a large osprey she had spotted in a tree. I got a couple shots of it in its perch before it started to fly. This was one of the first shots I took, as it swooped down in front of us. I spent a while trying to get a good Osprey In Flight photo on the second day when we happened upon several birds flying over a lake, not realizing I already had such a good one.

Junco

Junco

I’ve learned to recognize the juncos by the long, black and white tail feathers. That’s usually all I see as the flitter about in the shrubs. I had never seen one stay still for long enough for me to get a good look at it. They’re actually much more interesting — with the reddish, blueish, brownish coloration — than I had realized.

Red Squirrel

Red Squirrel

The red squirrel made the cut due to abundance rather than exoticness. These guys don’t like it much when you encroach on their territory. They’ll yell at you with a long, rattley-chirpy kind of sound. This guys seemed particularly peeved by our presence.

Juvenile Bald Eagle

Juvenile Bald Eagle

The second day started much like the first day: with Martha excitedly asking me to pull to the side of the road. She had spotted a large bird in a tree, as we passed at relatively high speed. She said it might be another osprey, but we had all day, so it was worth a look. We found this bird, which is clearly not an osprey. She thought it might be a juvenile bald eagle, only because it was the right size, and we were in the right part of the park. When we reached a ranger station, we found a bird book, and confirmed that it was a juvenile (2nd year) bald eagle. (We later double-confirmed with Fred.)

Sharp-Shinned Hawk

Sharp-Shinned Hawk

I noticed this one early in our hike on the second day. While tracking it as it flew from tree to tree, some other hikers came wandering down the trail, discussing the turmoil in Ukraine and Russia. One of them asked, “Anything interesting up there?” I pointed out the hawk. “Okay,” he replied in a tone that suggested he was annoyed that his conversation had been interrupted for something so pedestrian (metaphorically speaking, that is).

Long Tailed Weasel

Long Tailed Weasel

After taking a break to eat some peanut butter sandwiches we had packed, Martha started hiking again; I was a moment behind. When I reached her, she was frozen with excitement. “AARON! I JUST SAW A WEASEL!” There was a moment when we both were beginning to lament that I wasn’t at the ready with the camera before the weasel disappeared. But then it popped its head out of the brush to inspect the human interlopers disturbing its forest. I got a picture before it disappeared again. Then it appeared again on the other side of a log, and disappeared yet again. It seemed to have a difficult time deciding whether to be fascinated by or terrified of us. In any case, I got several pictures of it inspecting us from various vantage points. To this day, Martha will still, apropos of nothing, blurt out, “That weasel was sooooooooo great!”

Golden Mantled Ground Squirrel

Golden Mantled Ground Squirrel

Sticking with the small mammals for a moment, this one was good enough to pose in nice light. Unfortunately, he (she?) skeetered away before I was able to move into a position where his (her?) little snout wasn’t obscured.

Trumpeter Swans

Trumpeter Swan

They mate for life, so that’s kind of interesting. This is one of the second pair of swans we came across.

Golden Eagle

Golden Eagle

Most of the time when I call out, “BIRD!” Martha informs me that it’s a crow or a vulture. Yellowstone has an abundance of ravens, so during this trip, I became an expert raven spotter too. Large, black birds seems to be my specialty. I noticed this bird flying overhead during the hike, and I attempted to take a picture because 1) it seemed like quite a large bird, and 2) I was honing my birds-in-flight photography skills. Neither of us got a good enough look at it against the bright sky to recognize it, and we couldn’t make it out by reviewing it on the camera’s viewfinder (particularly difficult on a bright day). A moment later, we smelled a dead animal, and noticed some vultures overhead. We decided it must have been another one of my famous vulture spottings. So you can imagine my delight when, in later review, Fred declared it to be a golden eagle.

Bison

Bison

If you go to Yellowstone, there are two sights you can be sure you’ll see: geysers and bison. Just drive around a bit, and you’ll see each from the safety of your car. The thing about bison, you’ll hear over and over, is that you need to be careful around them. They seem like gentle giants who don’t mind all the people staring. However, if you get too close, they can be mean, angry, 1,200 lbs of beast. We were on a lightly used trail when we came around a corner to see this guy walking toward us along the trail. This was the second “sighting” of this sort in 30 minutes for us, so we wasted no time beating a path through the brush to give the bison a wide berth as we wondered whether our bear spray would work on a bison.

White Crowned Sparrow

White Crowned Sparrow

Props to the bird for posing in such nice light!

Sandhill Cranes

Sandhill Cranes

We saw several of these cranes flittering about. It’s not a fantastic shot, but I like their gangly legs as they are coming in for a landing.

White Pelican

White Pelican

This bird was in a marsh by the side of the road. From a distance, we thought it might be another trumpeter swan, but they are normally found in pairs. We got closer to watch it scoop up dinner in its big beak (which, as they say, “holds more than its bellycan“).

Chipping Sparrow

Chipping Sparrow

By our third day, after seeing so many large and unusual birds, we start paying more attention to the small birds. We saw juvenile western tanangers, townsend’s warblers, western wood pewees, and a variety of other interesting, but easily overlooked, birds. (We also saw a steller’s jay that would have made a nice picture if it had been a bit more cooperative, and showed us more than its butt. We also saw a kestrel fly across a lake and land on a distant tree — too far to get a picture could show the bird as anything more than a few blurry pixels.) This chipping sparrow is probably one of the least interesting birds we saw, but I happened to click the shutter at exactly the right moment. This picture, therefore, is illustrative of two things: 1) a chipping sparrow, and 2) the fact that 10% of nature photography is technical skill while the remainder is split between patience and dumb luck.

Bird In Tree

Bird In Tree

We have no idea what this one is, but I like the bird in the dead tree against the clouds. As I spent a few moments trying to get the exposure right, Martha kept telling me that it’s too far away, and that we wouldn’t be able to identify it. I told her, “I know, I KNOW! I’m just trying to do something here!”

Bald Eagle

Bald Eagle

And of course, there’s this guy. After sitting on the side of a road, watching several pronghorn antelopes gallop across a meadow, we were getting back into the car to move along when Martha spotted the eagle gliding across the sky, before it landed on a tree behind us. This was neither the first nor last bald eagle we saw during the trip. Still, I can never see an eagle without thinking of Gilbert & Sullivan.

 

programming

The Obsessing Over The Splits

“There’s one more piece,” I explained to Martha, “that you have to master.” The previous fall, she had developed a fibroma in her foot that curtailed her running. Hoping to keep her active (ie, non-grumpy), I dragged her to the pool. She never claimed to enjoy swimming, but on Monday and Wednesday nights, she would make sure I was planning on swimming the following morning. Even if she felt like it was a constant struggle, in a few months, she had improved significantly (ie, not nearly as much gasping and clinging to the side of the pool as when she started).

In the spring, she surprised me with her keenness to spend time on a bike. At first, it was mountain biking in West Virginia. Then she got a BikeShare membership so we could ride in Rock Creek Park on the weekends, when they close Beach Drive to traffic. Then she started talking about getting her own bike. After years of referring to bikes as, “The Vehicle Of Death,” I wasn’t sure what to make of it. But I was happy to go along with it. Eventually, I casually mentioned that, what, with all the swimming and biking, she might as well sign up for a triathlon. And much to my surprise, she was game!

I hadn’t raced a tri since 2008, so I was looking forward to a return to the sport. I picked Luray Triathlon (international distance — 1500 meter lake swim, 40km bike, 10km run) in August as a target race, and we got about to training. Well, there really wasn’t so much “training” in a specific sense. I mean, we’d go to the pool once or twice a week, we’d do 40-50 mile bike rides (far longer and hillier than the bike portion of the race) pretty regularly, and running is our bread and butter.

Long story short, she had a great race, despite coming out of the water pretty close to the tail end of the field. She tells the full story on her blog, so I won’t restate it all. But after the race, there was one last lesson of triathlon that she needed to learn — one more piece to master.

“Part of the triathlon experience is obsessing over the results.” In a running race, you might have intermediate splits, but after looking at the results, all you can really say is, “I gotta run faster.” Or maybe, “Look at that positive split! I gotta not race like a friggin’ moron!” But in triathlon, you get your finish time, but also times for the swim, bike, run, and two transitions. So you can say things like, “My swim, bike, and run were awful, and my first transition was slow as dirt… But I ROCKED my second transition!” Yes, obsessing over results, and imagining how much more awesome you would be if you could only swim faster is a grand part of the triathlon tradition.

Looking at Martha’s splits, it’s clear that she’s a weak swimmer (4th percentile of the race), a fair cyclist, and a standout runner (10th overall, including elite men). This seems like a time for some visualizations! The first step was to put the results into a CSV file, and load it into R. I wrote a little function to convert the times to total second, so everything could be compared numerically.

getTime <- function(time) {
  sec <- 0
  if ('' != time) {
    t <- as.integer(strsplit(as.character(time), ':')[[1]])
    sec <- t[1]
    for (i in 2:length(t)) {
      sec <- sec * 60 + t[i]
    }
  }
  sec
}

And I used that in a function that compiles the splits in to a vector.

getSplits <- function(results) {
  splits <- c()
  for (i in 1:length(results$TotalTime)) {
    swim <- getTime(results$Swim[i])
    t1 <- getTime(results$T1[i])
    bike <- getTime(results$Bike[i])
    t2 <- getTime(results$T2[i])
    run <- getTime(results$Run[i])
    penalty <- getTime(results$Penalty[i])
    total <- getTime(results$TotalTime[i])

    if (0 == t1) t1 <- 180 # Default of 3m if missing T1
    if (0 == t2) t2 <- 120 # Default of 2m if missing T2

    # If missing a split, figure it out from total time
    known <- swim + t1 + bike + t2 + run
    if (0 == swim) swim <- total - known
    else if (0 == bike) bike <- total - known
    else if (0 == run) run <- total - known
    
    if (swim & run & bike) { # Exclude results missing two splits
      splits <- c(splits, swim, t1, bike, t2, run, penalty)
    }
  }
  splits
}

From there, I could produce a graph showing color-coded splits in the order of finish for the race.

splits <- getSplits(results)

barplot(matrix(splits, nrow=6), border=NA, space=0, axes=FALSE,
        col=c('red', 'black', 'green', 'black', 'blue', 'black'))

# Draw the Y-axis
axis.at <- seq(0, 14400, 1800)
axis.labels <- c('0:00', '0:30', '1:00', '1:30', '2:00',
                 '2:30', '3:00', '3:30', '4:00')
axis(2, at=axis.at, labels=axis.labels)

Luray Intl. Distance Tri, Overall

Each vertical, multi-colored bar represents a racer. The red is the swim split, green is the bike, and blue is the run (with black in between for transitions, and at the end for penalties). It becomes clear from this graph that Martha was one of the last people out of the water (notice her tall red bar), then had a fair bike ride, but didn’t make up much time there. It wasn’t until the run that she started to make up time. That’s what moved her from the tail end of the field to the top half.

But part of the beauty of obsessing over triathlon results is that there are so many ways to slice and dice the data. It seems only fair that we should look at the sex-segregated results, and of course, triathletes are very into age group results. So we can limit the sets of data to our individual sexes and age groups.

Luray Results

So that’s one way to look at the data. However, that only provided a fuzzy notion of how each of us did in the three sports. For example, my swim time is similar to the swim times of many people who finished with similar overall times. It’s difficult to tell where I stand relative to the entire field.

Perhaps a histogram is more appropriate. For example, I could use my getTime function to create a list of the finish times for everyone.

times <- sapply(results$TotalTime, getTime)

Then it’s trivial to draw a histogram of finish times.

hist(times, axes=FALSE, ylab='Frequency of Finishers', xlab='Finish Time',
     breaks=20, col='black', border='white', main='Histogram of Finishers')

To draw the X-axis, I created a function that translates a number of seconds to a time string with the H:MM format.

# Make a function to print the time as H:MM
formatTime <- function(sec) {
  paste(as.integer(sec / 3600),  # Hours
        sprintf('%02d', as.integer((sec %% 3600) / 60)), # Minutes
        sep=':')
}

# Specify where the tick marks should be drawn, and how
# they should be labeled
axis.at <- seq(min(times), max(times),
               as.integer((max(times) - min(times)) / 10))
axis.labels <- sapply(axis.at, formatTime)

# Draw the X-axis
axis(1, at=axis.at, labels=axis.labels)

That gives me this:

Luray 2014 International Distance Results, HistogramI’ve also inserted an ‘A’ below the results to notate where I finished, and an ‘M’ to notate where Martha finished. However, as I’ve indicated, part of the obsessing over the splits involves slicing the data as many ways as possible. I wanted to see this sort of histogram for each of the sports overall, by sex, and by age group. That’s a nine-way breakdown, for both me and Martha. Fortunately, since the data is all in R, and since I have the code all ready, it’s fairly trivial to make the histograms. They need to be viewed a bit larger than the width of this column, so you can click on the images below to see more detail. Here’s mine:

Luray Histogram, AaronLooking at my results, it is clear that I’m a stronger swimmer than cyclist, but it’s really the run that saves my race. Here’s Martha’s:

Luray Histogram, Martha

Notice that in her age group, she had the slowest swim, and the fastest run. She clearly gets stronger as the race goes on.

But there is still (at least) one more way to look at the results. Not only do we want to know how we perform in each of the disciplines; we also want to know how we progress through the race. That is, how do our positions change from the swim to the bike to the run to the finish? I started off with a function similar to “getSplits” above. I called this totalSplits. For a given racer, this produced a vector of the cumulative time after six points in the race: swim, t1, bike, t2, run, penalties. I could use those vectors to build a matrix, which I could then use to build a graph of how race positions changed from the swim to the bike to the finish.

all.totals <- t(matrix(apply(results, 1, totalSplits), nrow=6))
# Exclude results that are incomplete
all.totals <- all.totals[which(all.totals[,6] != 0),]
cnt <- length(all.totals[,1])

# Map the swim, bike, and finish times onto a range of 0 to 1, with
# 1 being the fastest, and 0 being the slowest.
doScale <- function(points) {
  1 - ((points - min(points)) / (max(points) - min(points)))
}
scaled.swim <- doScale(all.totals[,1])
scaled.bike <- doScale(all.totals[,3])
scaled.finish <- doScale(all.totals[,6])

# Plot points for swim, bike and finish places
plot(c(rep(1, cnt), rep(2, cnt), rep(3, cnt)),
     c(scaled.swim, scaled.bike, scaled.finish),
     pch='.', axes=FALSE, xlab='', ylab='',
     col=c(rep('red', cnt), rep('green', cnt), rep('blue', cnt)))

# Add the lines that correspond to individual racers
for (i in 1:cnt) {
  lines(c(1,2,3),
        c(scaled.swim[i], scaled.bike[i], scaled.finish[i]),
        col='#00000022')
}

# Add some axes
axis(1, at=c(1, 2, 3), labels=c('Swim', 'Bike', 'Finish'))
axis(2, at=c(0, 1), labels=c('Last', 'First'))

From that, I get something that looks like this:

Luray Results, Places

It looks like a crumpled piece of paper, so perhaps it needs some explanation. At the left is the placing for racers after the swim from the fastest swimmer at the top, to the slowest at the bottom. In the middle is the placing after the bike, and on the left is the placing at the finish. The first thing I notice is that there seems to be little correlation between placing after the swim and after the bike. The left side of the graph looks like a jumbled mess. The other thing I notice is that the top racers — note that prize money brought some pros to this race — are fantastic all-around. To pick out my results and Martha’s results, I highlighted them in aqua and yellow, respectively.

And for the sake of completeness, we need to break that down by sex and age group.

Luray Placing by Sex and AG

So yes, I suppose the moral of the story is that no one can obsess over results like a triathlete can obsess over results.

And in case anyone wants to play with the results, click the link to get the CSV of the results for the 2014 Luray International Distance Triathlon.

running

Hellgate Overview

[The following is an overview of the Hellgate 100k course. I originally wrote it in 2006, and I’ve amended it several times through the years. I’ve finished the race 11 times, so I don’t have much more to say about it, but I’ve decided to move the overview to this blog for the sake of content consolidation. D’I miss anything, or get it wrong? Feel free to append, extend, expand, propound, or offer your own observations in the comments.]

Hellgate 100k

Alrighty, folks. I was recently looking at a map of the Hellgate course to refresh my memory about how it goes. Then I realized that that was a terrible idea. I mean, after doing this race five times, the one thing you definitely don’t want to do is remember anything about it. But by the time I remembered that, it was too late. Yet the same desire that would make me say, “EWWW, taste this!” after drinking sour milk makes me want to share the memories. So here’s a handy little overview of Hellgate. (I should also note that Keith Knipling put together a far more high-tech overview of the 2007 race. Me, I use a highlighter and a map that I spread on my floor. Keith, he’s got heartrate data, GPS details and elevation profiles. How can I compete with that? I CAN’T, I TELL YOU! *sigh* So I just have to rely on my razor-sharp wit and boyish good looks to keep you interested in what I have to say.)

I’ll give you the full map immediately below. After that, I’ve broken it down, aid station to aid station. I’ll give you Horton’s description of each section, followed by the effluvia of my ruminations. In the map below, the race starts in the upper right, and follows the yellow highlighter generally toward the lower left. The start, finish and aid stations are marked with little red stars. The map I used for this little presentation is,

National Geographic Topographic Map #789
Lexington, Blue Ridge Mts
George Washington and Jefferson National Forests
Virginia, USA
Featuring: Glenwood / Pedlar Ranger District
ISBN: 1-56695-118-6
http://shop.nationalgeographic.com/product/615/803/246.html

I originally put together this overview before the 2006 race. During subsequent years, I realized that there were some sections that I needed to update because I had remembered some details incorrectly. But most of all, I realized that this sort of overview could be only marginally useful. Hellgate, more than any other race I’ve done, has a character that changes drastically from year to year. I’m not just saying that some years it’s chillier than other years. I’m saying that from year to year, this is a completely different race. One year, a certain section of the course might be particularly difficult, and the next year, that same section might be… less notable.

So far, we’ve had,

  • 2003 – The first year of the race, no one knew what to expect. The weather was cold, and there was a light fall of snow on the ground. The moon was full, and the sky was clear. With no leave on the trees, no clouds in the sky, and white snow on the ground, the moon lit up the trails like daylight. I turned on my flashlight for the more technical downhills, but I ran most of the way by the light of the moon. And the end of that first year, everyone knew we had been part of something special. And we were all amazed at just how difficult the race was.
  • 2004 – The “warm year” was different, in that there was no moon. I was quite comfortable in shorts. When I finished, I wondered how I could have forgotten just how difficult the race was.
  • 2005 – The “ice year” was just ridiculous. Several inches of snow fell early in the week. On friday, the temperature rose to the 60s, then fell at night to the 20s. Every road section was covered with glare ice, and every trail section had fluffy snow under a half-inch thick crust of ice. Staying upright was the name of the game. Just walking across the parking lot at Camp Bethel, from your car to race registration, was a harrowing experience. When I finished, I wondered how I could have forgotten just how difficult the race was.
  • 2006 – The “cold year” (or “the year of the leaves”) was when we learned that eyeballs can, in fact, freeze. With temperatures around 12°F at Headforemost mountain, and strong head winds, things got ugly. Four people ended up with severely impaired vision when their corneas froze later in the race. (After thawing out, everyone’s vision returned to normal.) Further, due to a lack of recent rain, leaves piled up as high as a foot and a half deep on many parts of the course. With uneven trail and loose rocks underneath, the leaves made footing extremely difficult. When I finished, I wondered how I could have forgotten just how difficult the race was.
  • 2007 – The “nice” year was probably as good as it gets. Most years, the 10 or 15 minutes before the race start, as we stand around in our Lycra® and our Polartec®, can be painfully cold. This year was rather nice. I was in shorts, and not particularly uncomfortable (which meant the temperature was in the upper 30s). There had been very little rain leading up to the race, so even the early creek crossing was a non-issue. There was a little bit of ice on some of the roads at higher elevations early in the race, and there were some deep leaves covering trails later in the course, but neither was as bad as previous years. We finally had a year when we could judge whether the race was difficult because of the weather of previous years, or because the course was just that hard. I’ll let you guess what the conclusion was. But I’ll give you a hint: about two seconds after I crossed the finish line, I was flat on the ground. Oh yeah, and when I finished, I wondered how I could have fotgotten just how difficult the race was. (Though I should mention that this year was a very special race for me. The full story is here.)

Are you picking up on the theme here?

Hellgate 100K Course

read more »

electronics

An Arduino-Based Computer For The Jeep

In my early 20s, I made what, at that point, was the biggest purchase of my life: my little, green Volkswagen. In both a literal and figurative way, it carried me through some formative years. After 11 years, when repair bills were starting to exceed the value of the car, it finally became time to retire The Green Machine. (It wasn’t an easy decision, but I got a very large estimate to weld out a bad catalytic converter, and weld in a new one that would be necessary to get the car to pass its emissions inspection.) In its place, I wanted something that would handle snowy mountains a bit better — that meant four-wheel drive — and something that I could pay for in cash without totally draining the kitty. I ended up with an 11 year old Jeep Wrangler.

The Jeep has several drawbacks over the Volkswagen. It’s loud. It’s a rough ride. Despite seeming to be quite a bit larger, it doesn’t have much carry capacity at all — packing the car for any long trip becomes an exercise in applied geometry and spacial relations. However, it does have one big advantage: it is user serviceable. It’s a great car for modification and personalization. All cars should be so modular. When a side mirror recently broke, my only problem was deciding what kind of mirror I wanted to replace it with. I browsed through the options on Quadratec, picked a set, they arrived two days later, and it took me 20 minutes to replace both mirrors. When I decided that the stock headlights were too dim, I bought new enclosures for a different bulb type, and swapped the old for the new. Busted radiator? Got a new one at the local auto parts store, and swapped it out. Want seat heaters? Add a fuse block, and wire them to switches on the dashboard. (I’m sure I’ll post more about that one later.)

Since I’ve been driving the Jeep, one feature of the VW I have longed for is the little computer that would tell me the temperature outside, how long I have been driving, and my average speed. Maybe I care too much for stats, but I liked to know, eg, This trip was 19 miles, it took 26 minutes, and it is 68° F outside. The Jeep doesn’t even have a clock on the dashboard. No, to be able to see the time, I need to leave the radio (also an aftermarket replacement) on the clock display.

I finally took up the challenge to put together something that would give me the information I so yearned for. I decided to use an Arduino as the microcontroller for the project. I went to my other favorite site, Adafruit, and ordered most of the parts I’d need, such as a digital temperature sensor, a GPS shield, and a touchscreen display. When the parts arrived, it was time to get soldering.

Parts to solder

I had to solder the header pins to the GPS shield, and a set of wires to both the GPS shield and the touchscreen in order to connect them to each other. I didn’t want to connect them directly. The plan was to set it up so the microcontroller/GPS unit would be hidden under the dashboard. The display would be affixed to the top of the dashboard. The temperature sensor would be mounted to the front of a front wheel well, and wires would be run back through the engine compartment, and through a small hole I had drilled in the firewall. But before I could do all of that, I wanted to make sure the basic unit worked. Once I figured out how to interface with the temperature sensor, the touchscreen, and the GPS, it wasn’t particularly challenging to write code to pull data from the sensors, and spit the information to the display. I connected the display to the microcontroller/GPS unit through a breadboard, and plugged a 9V battery into it. It was a self-contained unit that I could plop on top of the dashboard.

Computer on dash

I’m holding the display, which is connected (through the breadboard) to the GPS shield which is plugged in to the Arduino, which is powered by a 9V battery. The display shows the time of day at the top. On the left is the outside temperature (“??? F” since it is not currently connected to the temp sensor), current speed, and altitude above sea level. On the right is current trip information: time, distance, and average speed (“0.0 MPH” because of a bug in my code at that time). At the bottom is the latitude and longitude, and a green dot, indicating that the GPS has a fix.

Once I was generally satisfied with how the device was working, I needed to replace the breadboard with a more convenient connection. I needed to connect nine wires, so I started digging around for a standard RS232 serial cable with a DB9 connector on both ends. Fortunately, I keep around all sorts of old cable that will probably never be useful again. After digging around the box, I found a cable with DB9 connectors. I tested all the pins to make sure that I had a serial cable — where there is a one-to-one connection between pins on each end — and not a null modem cable — where a pin on one end might be connected to multiple pins on the other end. I was in luck; the cable would work. I picked up some solderable DB9 connectors from Radio Shack, and put one end on the display, and the other end on the microcontroller.

For the temperature sensor, I needed to be able to plug in three wires. I like the simplicity of a standard 1/8″ stereo jack, so I soldered a female end to the wires on the microcontroller, and a male end to the wires from the temperature sensor. So that’s an easy-peasy-parcheesi connection! The only trouble I had with the temperature sensor was joining the wires that ran through the engine compartment. The sensor itself is wrapped in a waterproof casing, and is connected to a 1 meter wire. But that wasn’t long enough to make it to the cabin. Joining longer wires to complete the run was not a problem, but securing them from the elements was a concern. So I picked up some dual-layer heat-shrink. Standard heat-shrink will shrink tightly around a join, but it’s still possible that moisture could get in. Dual-layer heat-shrink has an internal layer of adhesive that melts at a temperature lower than the application temperature. The adhesive fills in the gaps, and creates a waterproof layer — it’s preferable to standard heat-shrink for outdoor applications. So I made the joins, heat-shrunk each of the three individual wires, and tested it. Everything worked fine. I added one more layer of heat-shrink around all three wires, and tested again. The sensor no longer worked. I suspect that I over-heated the wires. Rather than using a proper heat gun, I was just waving a lighter under the heat-shrink. I think I was over zealous in my attempts at shrinkage, and I somehow ruined the connections or wires with too much heat. I had to cut out the connection, pull the remaining wires closer together, and start over. Eventually, I got it right.

Temperature Sensor

Clockwise from top left: 1) Under the front, drive-side wheel well. The white wire is connected to the temperature sensor. The sensor itself is on the left, wrapped in black Gorilla Tape, to add extra insulation against the elements. 2) Under the hood, the white temperature sensor wire comes from the bottom left up to the point where it is joined (with a length of black heat-shrink) to red, black, and green wires that run to the back of the engine compartment and through the firewall. 3) The wires from the temperature sensor terminate at a 1/8″ stereo plug.

For the GPS, I needed an external antenna, as the GPS chip would eventually be placed under the dash, where it would have a hard time finding a signal. I got an external, active antenna that I could place someplace where it would have good line-of-sight to the satellites. I found that the best location was on top of the dashboard. That made it easy to run the wire behind the dashboard, down to where the microcontroller would eventually be living. The antenna wire ends in an SMA connection (which is a small coax-type connection), so I us an SMA to uFL adapter to connect it to the uFL connector on the GPS shield.

The antenna is mounted on the dashboard. The wire runs behind the dashboard, and terminates in an SMA connector, which is connected to a uFL adapter.

The antenna is mounted on the dashboard. The wire runs behind the dashboard, and terminates in an SMA connector, which is connected to a uFL adapter.

The final piece of the puzzle was power. Fortunately, for other purposes, I had previously installed an extra fuse box in the Jeep, and I had a few spare switched (ie, on when the car is on; off when the car is off) leads in the cabin. I connected one to a 2.1mm power connector, and that was all I needed to do to power the microcontroller. However, when I took the whole contraption for a ride, I noticed that the Arduino ran very hot. The car provides a fairly dirty 12-14 volts, with possible spikes that could get to 18 or 20 volts. Based on the Arduino specs, the on-board voltage regulator should be able to handle that. But aside from my own observation that the device became worryingly hot, research seemed to indicate that it was only a matter of time before I fried the device. So I decided that I’d try to feed it a clean 7 or 9 volts. (It needed to be at least 7V because the GPS shield required 5V, and the on-board regulator would cause a drop of at least 1.5V from whatever I supplied.) I considered cheaping out, and just adding a standard, 7807 or 7809 voltage regulator. But in case I end up packing everything together in a tight space, I didn’t want to have the heat dissipation issues of a voltage regulator, so I went with a much-more-expensive buck converter. Whereas a voltage regulator reduces voltage by dissipating excess energy as heat, a buck converter is a highly efficient electronic device that will step down voltage with minimal waste. I hunted down a Traco TSR 1-2490 and installed it inline with the power connector.

A Traco TSR 1-2490 buck convert is connected inline with the power connector to supply a clean 9 volts.

A Traco TSR 1-2490 buck convert is connected inline with the power connector to supply a clean 9 volts.

Since I haven’t finalized the installation, the cockpit of the car is a mess of wires that I can connect to the microcontroller when I put it into the car.

mess_of_wires

And the controller itself is sort of a mess (but somewhat less delicate that you’d think — yay for solid solder joints!).

The Whole Kielbasa

But hey, it works! So the next step is to make some custom enclosures, and tidy everything up. I have some ideas, but I might not get around to it for a few months.

Display

bike

A New Old Bike

In the late 90s, my parents gave me a Specialized Crossroads A1 Expert hybrid bike. At the time, it was the nicest bike I had ever owned — aluminum frame and 7-speed with a triple (or “21-speed” depending on your preferred nomenclature). I would tool around on the bike paths for a few miles at a time, and eventually, I trained for my first triathlon on that bike (though I did the race on a borrowed road bike).

In the years since then, I’ve had an array of bikes — triathlon, road, fixie, mountain bike — each serving a different purpose. Several years ago, my father asked if I was using the Crossroads, and if I wasn’t, he was interested in taking it so he could run short errands on it. He used it for a while, but for the past few years, the bike has been sitting in my parents’ garage, unused and unloved.

The last triathlon I did was an iron-distance race in 2008. In 2009 and 2010, I was focused on running, and since then, I had been so exhausted with Lyme disease that I could never muster the energy to do much swimming or biking. But a few changes have gotten me back on the bike:

  1. Since addressing the whole Lyme thing, I’m returning to my old energy levels.
  2. Spending a week crewing for my friend, Kiwi Chris, as she completed a quintuple iron-distance triathlon (12 mile swim, 560 mile bike, 131 mile run) made me nostalgic for all the good times and adventures she and I had on the bike over the years, and I realize how much I missed riding.
  3. I continue to have severe bursitis in both of my heels. I’m fairly certain that the inflammation was originally due to the Lyme, but at this point, it is somewhat chronic. My heels are better than they were a year ago, but it is entirely possible that it could be years — if ever — before I can run entirely pain-free. So my weekly running mileage is dictated by what my heels can handle. But biking doesn’t seem to cause pain or problems.
  4. Martha has been struggling with a few running-related injuries that have similarly limited her weekly mileage. So I’ve been introducing her to the joys (though she might use a different word) of swimming and biking.

To get in a few miles on the bike, I found a reasonable route to the office, and I started bike commuting occasionally. Living in Washington, DC, and commuting on a route that takes me over bumpy, pot-holed roads, craggy sidewalks, and a little bit of dirt, I’d use my mountain bike for the ride. It was a bit of overkill, but I decided that it would be better for my wee, little bum than trying to ride my road bike. Since I wasn’t doing much road riding, I left the road bike in storage, and I’d keep the mountain bike in the bike storage room of the co-op  where I live.

One day, when I went to get my mountain bike, I found an empty space in the bike storage room when my bike had been. The door leading outside from the bike storage room had been having trouble with the lock, so I assume that someone had come in from outside and picked the nicest bike in the room to steal. At the same time, Martha was getting more interested in riding (or at least, becoming a more willing participant). So I had pulled my road bike out of storage, and taken indefinite loan of a friend’s old bike for Martha to ride. Operation Ride More Bikes was in full swing, but we had hit several hitches:

  1. I was lacking a bike suitable for commuting to work.
  2. Aside from my non-existent commuter bike, we had two bike that could not be left in the bike room (since the bike room was clearly not secure), yet we live in an apartment that is barely big enough for two adults and a cat.

Before I could address point #1, I had to do something about point #2. Fortunately, we have high ceilings and solid walls. My first attempts to drill into the studs failed. But a new carbide drill bit made quick work of it.

 

Bikes on a wall

A nuisance becomes an objet d’art! The cat approves.

Once I had gotten the road bikes out of the way, I could focus on my commuter. The old Crossroads was available.

Bike before

The frame was perfectly good, but the 7-speed drivetrain was due for an overhaul. Further, I don’t like riding in tight spaces with straight handlebars. I started spec’ing out parts to turn it into a cyclocross-style bike. I didn’t want to pour thousands of dollars into it, but I wanted to build a bike that could take a beating and would last. I considered going with Campy or SRAM, but I’ve always used Shimano, so I stuck with what I know. I like the 105 line as a good compromise between price and quality. So I ordered a bunch of parts — a new bottom bracket, cranks and chainrings, a cog set, deraillures, levers — and started to strip down the bike.

Stripped bike

Getting out the bottom bracket was the hardest part. It was seized with 16 years of dirt and grime. Fortunately, some WD-40 and a 24″ breaker bar did the trick.

My strategy was to replace only as much as necessary to convert the bike to a Shimano 10-speed drive train (with a double) and drop handle bars. I had to hunt around a bit for an inexpensive rear wheel that would fit the 135mm dropouts, but once I had that, I was ready to go. The build-up was pretty easy.

My new bike

As much as it sucked for my mountain bike to be stolen, I’m really, really happy with my new old bike. It brings together the best qualities of my mountain bike (softer ride) and my road bike (faster ride) when cruising around the city.

There are a few to-do items remaining for the bike, but none of them is stopping me from riding the steed.

  1. New pedals: I currently have platform pedals with single-sided SPD attachments. I’d prefer double-sided SPD pedals with no platform.
  2. New brakes: I considered picking up some new brakes, but I decided that it wasn’t absolutely necessary. The current brakes are old, but still functional. If the bike works out, next summer, I’ll upgrade. For now, I just put in new pads.
  3. New stem: This was my biggest miscalculation. I didn’t realize that modern drop bars have a different diameter at the center than old drop bars. None of the old quill stems I had laying around would work with the new bars. So I had to order a quill stem adapter, and a new stem. The stem I got is 100mm, but it turns out that that’s too long. To avoid being overly stretched out, I have to jam the seat way forward. It’s not an ideal fit, but it works for now. Again, if the bike works out in the long term, I’ll pick up a 50mm stem and fix the fit.
  4. New headset and fork: The headset is in terrible condition. It’s still smooth, but externally, there’s quite a bit of rust. If I had a headset press handy, I’d probably take care of this sooner rather than later. However, I’ll either need to borrow the tools from someone, but build my own DIY headset press. (I do few enough headsets that I don’t want to pay an extra $100-$150 just for the tools.) Whenever I do the headset, I’d like to convert to threadless, and replace the fork as well.
  5. New seat post: This is purely aesthetic, but I think I’d be happier with a clean, matte black seat post. Maybe I’ll just wrap the current post with electrical tape and call it a day.
  6. New deraillure hanger: The deraillure hanger is slightly bent, which means that if I were to shift into my biggest cog (easiest gear), the spokes on the rear wheel would rip off the chain tensioner. For now, I have the limiters set so I don’t accidentally cause that to happen.

I wanted to take some pictures of the bike all shiney and new, but actually riding it took precedence. So these pictures are after a few rides (and one commute to work). Please excuse the shmutz.

Drivetrain

Levers

Breaks

Stem

Saddle

nonfiction

Let It Marinate

In my first year of college, my dorm was configured as a suite, with five rooms around a common living area. One of my suite mates was a fellow named John whose primary motivation in all activities was to bring ladies to his room to “rub”.

“I’m goin’ out with this lady tonight, then we gonna’ come back to my room an’ rub,” he’d say. Except he never said “rub” as a normal person would say “rub” (fittingly enough). He would always elongate the “u”. Ruuuuuuuuuuuub. As in, We gonna’ ruuuuuuuuub.

John was always a great source of amusement to me. He could easily have crossed the line of creepiness, but he seemed to be able to stay on the right side of that divide (barely) by becoming a sort of caricature of himself.

His term of choice—ruuuuuuuuub—was part of his charm. It’s meaning in the given context was clear. Yet, by itself—rub, without the elongated vowel—it’s a fairly innocuous word. I decided one day that I was interested in learning more about what was involved in John’s favorite pastime.

“I’m goin’ out with this lady tonight, then we gonna’ come back to my room an’ ruuuuuuuuub.”

“John, man,” I said, “how does one ‘ruuuuuuuuub’?”

“C’mere, lemme show you somethin’.” He gestured for me to come to his room. Aside from the lamp draped with a sheer piece of fabric to add a slight red tint to the light of the fluorescent bulbs above, nothing about the room struck me as particularly conducive to what I had interpreted ruuuuuubbing to involve. I looked around the room, then stared at him blankly. He smiled at me. “Hold on,” he said as he walked to the light switch, and flipped off the lights above. We were now staring at each other in the dim, red light of the incandescent lamp. “Check it,” and he pointed at the ceiling.

His ceiling was covered with the sort of adhesive, glow-in-the-dark stars that a fifth-grader might use to decorate his room. But that wasn’t what he was pointing to. He was pointing to the spot directly above the head of his bed. He had taken a sheet of the same material used for the stars, and with the skill and accuracy of a young child, cut out letters to form the word RELAX. I can’t say for certain, but I would imagine that if I were a female, and some fellow had flipped off the lights to reveal a sloppily cut, glow in the dark RELAX on the ceiling, I would do anything but.

Now, like John, I was smiling—but for a different reason. “So this is part of ruuuuuuubbing?”

“First, you set the mood.” He paused and smiled even more broadly. “Then you let it marinate.”

In my entire college experience, I attended many lectures. In each of those lectures, a professor hoped to teach some lesson that would, at least in some small way, shape the minds of the students in the class. Yet I would be hard pressed to provide an example of a lesson that made more of an impact on me than what John taught me that day. First, you set the mood. Then you let it marinate. True, dat.

knitting

Faux Cable Hat

Download the pattern: Faux Cable Hat

The standard technique for moving a column of stitches across a pattern is cabling, in which one or more stitches are passed over one or more other stitches while knitting a row. However, a column of stitches can also be moved across a pattern by balancing increases on one side of the column with decreases on the other side of the column. As an exercise in this technique, I started drawing up a chart with two such columns, criss-crossing is opposite directions.

I ended up with what I call my Faux Cable Hat. It’s a subtle pattern — without the bulk of real, honest-to-goodness cables — that looks best in a single color yarn.

Also, it can be knit with either a foldable brim, or a short, simple brim.

One note about the increases: All increases have either a “left” or “right” lean, specified as M1L and M1R, respectively. M1L is made by lifting the bar between the current two stitches from the front, and knitting through the back loop. M1R is made by lifting the bar between the current two stitches from the back, and knitting through the front loop. Further information about these two techniques can be found at,

http://www.twistcollective.com/collection/component/content/article/92-how-to/1046-make-1-left-or-right-m1-m1l-m1r

I occasionally become bleary-eyed, and forget which type on increase requires lifting the bar from which side. Eventually, I came up with the mnemonic that M1L lifts the bar from the Front, because L and F are similar (both letters are constructed with only horizontal and vertical lines). Likewise, M1R lifts the bar from the Back, because R and B are similar (both letters are constructed with a rounded shapes).

Download the pattern: Faux Cable Hat

programming

Race Progress Visualization Using D3

[The project referred to in this post can be found at http://vestigial.org/MMT/ ]

I’ve been looking for some better tools to produce interactive, data driven, visually appealing web content. In the past couple of years, I’ve become enamored with R for analysis and visualization, but the graphic results are static. (Sure, there are tricks to create animations, but I’m not looking for workarounds.) I occasionally use Google Charts when I need to put together a quick visualization, but they don’t provide quite the level of flexibility I’d like. I started looking at either working directly with SVG or Canvas DOM elements, or using a Javascript SVG library that would allow me to avoid the low-level details.

The most interesting possibility was the D3 framework. D3 — for Data-Driven Documents — is an entire framework for DOM manipulation in data-driven sites. Browsing through the examples on the D3 site, I recognized several memorable visualizations that have appeared on one of my favorite blogs through the years, Flowing Data. It is possible to use D3 for SVG construction and manipulation while non-data-driven portions of the site are handled by, eg, jQuery or standard Javascript. But as long as you’re already using the bandwidth to load the framework, you might as well drop other frameworks, and use the tools that D3 provides.

I was keen to get some experience with D3. When learning a new technology, I prefer to dive straight in — come up with a short, but non-trivial project that I can build. In this case, I came up with a project that melds technology, data visualization, and ultrarunning. The Massanutten Mountain 100 Mile Trail Run (or MMT) is in a few weeks. In such a long race, runners and crews like to have some idea when they’ll arrive at intermediate points along the course if they’re aiming for some given finish time. Conversely, knowing when they’ve arrived at points along the course can help to predict what sort of finish time to expect. While I’m not the first person to provide a visualization, or some tool to correlate aid station splits with finish times, it’s fun to put together something that’s visually appealing and useful.

Showing data from 2011 and 2013 for finishers who finished between 20:59 and 25:55, race time. The horizontal axis is time and the vertical axis is distance, labeled on the left with mileage at each aid station, and on the right with the aid station name. Each diagonal line represents a single racer. Intermediate times on the graph show first and last racer times of arrival at each aid station (for racers in the result set).

Showing data from 2011 and 2013 for finishers who finished between 20:59 and 25:55, race time. The horizontal axis is time and the vertical axis is distance, labeled on the left with mileage at each aid station, and on the right with the aid station name. Each diagonal line, or “track”, represents a single racer. Intermediate times on the graph show first and last racer times of arrival at each aid station (for racers in the result set). Tufte would be proud.

 

There are several interactive components that I think are noteworthy. First, I provide on-demand data loading. When the page loads, none of the race results is loaded. When a year is selected, the page checks whether the data have been downloaded. If not, it fires an AJAX request, and saves the data so the results can be turned on and off.

The page also provides sliders to limit the result set based on finish time. Each limiter consists of three components: a triangular slider widget (represented by an SVG path element), a time display (represented by an SVG text element), and a vertical guide line (represented by an SVG line element). When the widget is slid, all three elements should move in unison, and the time display should update with the time value at the current point. As a bonus, the vertical guide gets brighter. So I needed to be able to address each element individually, but move them in unison. To build that, first I needed to define the shape for my widget (note that in SVG coordinates, the top left is [0,0]):

var limpolygon = [{x: 0, y: 0}, {x: 10, y: 0}, {x: 5, y: 10}, {x: 0, y: 0}];

I also need to define a function to tell D3 how to interpret the data above. I can use d3.svg.line() to return a function for this purpose. Since I’ve built the object with straight-forward X and Y coordinates, I just need to build a simple function based on those values:

var limline = d3.svg.line()
  .interpolate("linear")
  .x(function(d) { return d.x; })
  .y(function(d) { return d.y; });

Finally, I put the group together. I define a group element (“g”), and append the widget, which I construct in place. I then use the D3 selector to reselect the group, and add the line, then the text:

svg.append("g")  // Create the group, append it to the svg object
  .attr("id", "lim1")
  .attr("transform", "translate("+lim1x+","+limy+")")  // Put it into position
  .append("path")  // Create "path" element for widget, and append it to group
    .attr("id", "lim1_point")
    .attr("d", limline(limpolygon))  // A path has a "d" attribute which gives
                                     // instructions for drawing. Our limline()
                                     // translates raw data into path data
    .attr("fill", "white")
    .on("mousedown", function() {
      capt = "lim1";
      d3.select("#lim1_line").style("stroke-opacity", "1");
    });

d3.select("#lim1").append("svg:line")   // Create line element, append to group
  .attr("x1", limhalfw)
  .attr("y1", ex_pad.top)
  .attr("x2", limhalfw)
  .attr("y2", height - ex_pad.bottom)
  .attr("id", "lim1_line");

d3.select("#lim1").append("svg:text")   // Create text element, append to group
  .attr("id", "lim1_time")
  .text("00:00")
  .style("text-anchor", "end")
  .attr("transform", "translate(-2)");  // Push it 2px to left, for a nice gap

In my view, the coolest trick is making the data respond to the sliders. Whereas showing or hiding the individual years relies on a small number (3) of discrete values, I need to show or hide individual race results based on what is essentially a continuous scale. This involves several steps. First, when adding each track to the graph, I need to attach the finish time to it. Fortunately, HTML5 provides the ability to specify arbitrary data attributes with the data-* construct.

lineset.enter()
  .append("path")
  .attr("data-finish", function(d) {  // Add the data-finish attribute
    return d.finish;
   })
  .style("stroke-opacity", function(d) {
    if (d.finish > finScale(lim2x) || d.finish < finScale(lim1x)) return "0";
    else return ".3";
   })
  .datum(function(d) { return d.splits; })
  .attr("class", "rtrack line " + iden)  // Classes to use later in selectors
  .attr("d", line);

Above is the code to add the tracks. While it might not make much sense if you are not familiar with D3, the key point is the third line. The object has a data object, d, applied to it, and on that line, we set the data-finish attribute to the value of d.finish. (Directly below that, we set the opacity of the line to 0 (making it invisible) if it falls outside of our specified range, or .3 if it is inside the range. But we’re getting ahead of ourselves.)

The next thing we need to a way to translate the location of a slider into a finish time. D3 provides “scales” for just such a purpose. Usually, D3 scales are used to translate some real world value to a pixel position. In this case, we want to do the reverse. I want to build a function that will translate an input domain of a pixel position into the output range of a race time, which in this case is between 0 and 36 hours.

var finScale = d3.scale.linear()
  .domain([lim1x, lim2x])
  .range([0, 36]);

(An astute reader who is familiar with D3 might note that somewhere else, I must have defined a scale to translate from times to pixel values. In that case, someone might wonder why I don’t just use linear.invert() to translate a range value into its corresponding domain value. The answer is that the scale that translates from time to position uses a domain defined by the time of day as a date object, whereas in this case, I want to translate between position and a floating point number representing the finish time in hours (with minutes represented in the fractional portion of the number). Hence the need to define a new scale.)

In this case, lim1x is the initial pixel position of the lower limit slider, and lim2x is the pixel position of the upper limit slider. That produces a function that can be called as finScale(px_pos) to return a corresponding race time. I can then use that in the function that is called when a slider is released.

function updateRange() {
  var fin1 = finScale(lim1x);  // Translate pixel positions to finish times
  var fin2 = finScale(lim2x);
  d3.selectAll(".rtrack").transition(500).style("stroke-opacity", function(d) {
    if (this.getAttribute("data-finish") > fin2 ||
        this.getAttribute("data-finish") < fin1) return "0";
    else return ".3";
  });

  updateAidStationTimes();
}

That function translates the current pixel positions of the sliders into race times (fin1 and fin2). Then it uses d3.selectAll to get every item with the class “rtrack” (which is every race line displayed on the graph), applies a 500ms transition time to the following step, then sets the stroke-opacity style based on a function that checks whether the custom attribute data-finish is in the range defined by the limiters. Finally, it calls updateAidStationTimes(), which I won’t explain in detail here, but it uses d3.extent() with a custom accessor function to find the first and last arrival time of racers in the result set at each aid station. (If you’re particularly interested, you can always dig it out of the source.) It then updates the times displayed on the graph, and moves them into the proper positions.

I started the project on Saturday morning with no experience in D3 (or with SVG graphics), and I finished Sunday evening. I even had time to get out for a bike ride, a run, and a trip to the library to get a movie (which I also watched over the weekend). In the course of this project, I came to appreciate just how massive D3 is. I’m starting to get a feel for it, but this project just scratched the tip of the D3 iceberg (though I’m not sure one would really scratch an iceberg, the tip or otherwise).

[The project referred to in this post can be found at http://vestigial.org/MMT/ ]

music

Traumerei

When I was very young — maybe around second grade — I started taking piano lessons from Mrs. Bickley, who also happened to be my school’s librarian. But I had little patience for practicing. Working through a new song, note by note, making the same mistakes again and again created such visceral frustration that there came a point when I refused to practice at all. Sometime during fourth or fifth grade, my parents allowed me to quit. I felt some shame whenever I would venture into the library and see Mrs. Bickley, but that couldn’t nearly outweigh how much I disliked practicing.

Some years later, when my brother was taking guitar lessons, I tried again. My parents could take us both to the music store with the sound-proof practice rooms in the back, and we could take our lessons. That time around, I lasted perhaps a year before deciding that it wasn’t for me.

In middle school and high school, I was involved in theater (some, of the musical variety) and choral groups. I wasn’t much of a singer, but it turns out that at certain times and places, if you are a male, it’s sufficient just to be willing to show up. I was the beneficiary of just such a situation.

Many, many years later, I found myself regretting that I didn’t stick with music. I’m envious of people who can sit down with an instrument, and play a song. As time went on, my regret grew more and more palpable. I still had a mini Casio keyboard that I received as a gift as a child. I plugged it in, and started to pick out songs on its miniature keys. After several weeks of the tinny, synthesized keyboard sound, I decided that it was time to commit. I bought a full-sized keyboard, and I started to play again. Whereas I had been an impatient child, I have become an adult who is quite content to spend an hour or two working through a troublesome section of a song.

I can’t claim that I’ve become a very good piano player. But I can pick through a song, and repeat it enough that it eventually starts to sound coherent. One of my favorites is Traumerei by Schumann. It’s short and melancholy and open to oh-so-much expression. Here, I play it too fast, and I’m sort of distracted by the concerns of self-recording. I hammer the keys too hard and unevenly in many places, and I continually turn even eighth notes into dotted eighth notes and sixteenth notes.

But it brings me joy to be able to sit down at an instrument, and play a song.

 

 

(I should note that the C above middle C on my keyboard is busted. The key itself is loose and most of the time, it doesn’t play when struck. So if you are paying close attention, you’ll notice that that note is almost entirely absent from the song. Also, I recorded the sound on Garageband on my iPad. For some reason, that app has recently decided that my songs really need occasional, randomly placed gong sounds. So again, if you are paying close attention, you’ll hear a couple of Garageband gongs.)

life

Grandma

Grandma passed away four years ago. The following is the eulogy I gave at her memorial service.


Grandma moved in with us when I was very young. She was a part of the family, and she helped my mother and my father raise me and my brother. I suppose that the prime directive of raising two boys is to get them through adolescence without allowing them to cause excessive harm to themselves or others. And as a testament to their success in that endeavor, my brother, Mark, and I are here today.

But if I were to claim that grandma only kept me out of harm’s way, I would be failing to recognize the deep impact she had on my life—on making me the person I am today. And while she influenced me in many ways, there was one lesson she taught me that stands above all others. It’s a lesson that she repeated throughout her life—to me and to everyone who came in contact with her. She never forced it on anyone, and most of the time you might not have recognized that she was offering a lesson at all. I didn’t. I didn’t realize it until many years after she started teaching it to me.

When I was young, I realized that grandma had a unique way of seeing the world. While other adults would talk about difficulties, she would talk about joys. When other adults would talk about how cold and rainy it was outside, she would talk about how warm and cozy it was inside. I thought that she just didn’t see somethings that other people saw—that she had some sort of blind spot for those things that most people dwell on.

Years passed, and I grew older. Eventually, I could talk to her as an adult. And as an adult, I realized something: I had been naive. She wasn’t missing anything. She could see the difficulties and travails of life just as well as anyone else. The difference between her and everyone else was that she had an amazing ability to put the bad aside, and focus on the good. She wasn’t an optimist because she couldn’t see the down side of a situation. She was an optimist because she chose to embrace the up side of all situations. Her optimism was intentional.

Grandma never tried to convince me that I should practice her brand of intentional optimism. No, she was content to let me become my own person, to find my own way. All the while—through my childhood and beyond—she was a presence, offering herself as an example of one way to see the world.

None of us can go through life without affecting, and being affected by, the people around us. Grandma lived for 96 years. Many people loved her, and she loved many people. In one way or another, she touched every one of us. When someone like Grandma passes on, those of us who loved her struggle to find a way to honor her and everything that she gave to us. I’m glad that we could all come here today to remember and honor her. But after we leave here, and return home, she will still be with us. Each of us has the opportunity to continue honoring her by embracing that most important lesson that she taught all of us: that we can choose to see the joy, the up side, the good in any situation. I know that every time I practice intentional optimism, a part of her carries on. And in that way, she will always be with me.