Saturday, November 30, 2013

Bike Brands at the Low-Key Hillclimbs

Starting in week 5 I began asking riders to describe the bike they were on when they RSVP'ed for the following weekend's Low-Key Hillclimb. We used to write this down at check-in, but it made it a lot easier to search the data if I had it entered digitally. So if we had a rider on a red and yellow bike and couldn't identify him I could search for all descriptions with both "red" and "yellow" for the bike and realize there was only one such description. We also ask for jersey color, but still write that down at the start, since I for one have problems planning this sort of thing ahead of time. But maybe others plan their wardrobes better, so I may add jersey description to the RSVP form as well.

But anyway, I decided to check what bike brands people were riding this year. So for rider numbers for whom I had a bike description (one per rider, so not counting the same rider multiple times if he rode multiple weeks), considered his bike description and wrote I Perl code to try and identify the bike brand from the description. This involved checking spelling ("Canondale") and mapping models to brands ("Tarmac" to "Specialized", "Ghisallo" to "Litespeed", "CAAD"-anything to "Cannondale", etc).

If I couldn't identify the make, the rider isn't counted For example, some left the field blank, others put just colors, one person put "road bike"...

Here's the results. We're a lot closer to Morgan Hill than we are to Madison, and the results reflect this:

#  type
60 Specialized
29 Trek
21 Cervelo
16 Cannondale
15 Giant
8  Khalsa
7  BMC
6  Calfee
6  Felt
6  Scott
5  Bianchi
5  Colnago
5  Willier
4  Fuji
4  Leopard
4  Look
3  Kuota
3  Pinarello
2  BH
2  CoMotion
2  Kestrel
2  Motobecane
2  Orbea
2  PedalForce
2  Serotta
2  Seven
2  Steelman
2  Volagi
1  Argon
1  Ducati
1  Faggin
1  Fondriest
1  GT
1  Guru
1  Ibis
1  Kharta
1  Klein
1  LeMond
1  Litespeed
1  Merlin
1  Moots
1  Neuvation
1  Redline
1  Ridley
1  Ritchey
1  Scattante
1  Soma
1  Teschner
1  Time
1  Tommasini

Thursday, November 28, 2013

Low-Key Hillclimbs 2013: personal report

Another year of Low-Key Hillclimbs has come and gone, ready or not.

When the series began in the first weekend of October I had been riding again for two months (Aug-Sep) after missing most of June + all of July to a groin injury from a bike crash. My focus during this period was on physical therapy, however, and my ride tended to be short and low-intensity. My progress from late Aug - early Sept took a step back when I devoted riding time to watching America's Cup racing. I started ramping up again at the end of September but I was nowhere close to where I needed to be.

I traditionally coordinate Montebello, week 1 of the series, and this year was as usual. Weeks 2 and 3 I volunteered, riding climbs both weeks in advance of the participants in order to take split times along the course (Montevina + dirt week 2, Bohlman week 3). These were good, solid, hard climbs, and were a nice boost to my fitness. I added an Old La Honda Wednesday Noon Ride late October, finishing just over 20 minutes, and another early November, finishing 19:14. I rode both of these on my steel Ritchey Breakaway with Gran Bois 26 mm tires inflated to something around 80 psi. There's a boost going to my Fuji SL/1 with carbon tubular wheels and time trial sew-ups pumped to 140-150 psi. So 19:14 wasn't where I'd like to see myself on the Wed ride, a minute faster would have been nicer, but it was close enough.

Week 4 I rode Lane Parker's 52nd century of 2013 and birthday ride instead of doing the GPS-timed Low-Key that week. Getting a 100 miler in, even if it was difficult and slow, was a confidence boost. Then week 5 was a transportation challenge, so I rode to the finish to help with results, hitting the course from the north. This was another solid training ride and I followed it up with more climbing (two San Bruno repeats on Sunday, then that Noon Ride OLH the following Wed).

So I was no longer "out of shape", but I wasn't exactly in shape either. That takes longer, especially at my advanced age. But I couldn't wait any longer, I had exceeded the scoring limits of volunteering, and I had to put some real times on the board.

I started with Patterson Pass, week 6. It felt really good to go out there and mix it up again, but it was a bit frustrating being relatively uncompetitive. Our group had difficulty gelling on the early, relatively flat portion of the climb, and we lost solid time there. The rest of the way I could ride tempo but had no punch, and I got gapped toward the end. I ended up with 106.8 points. I hoped to improve in future climbs.

Lomas Cantadas was next, and I got what I was after. There I started conservatively, saving something for the steep finish to the climb, and caught two riders I've for years treated as benchmarks for a good climb: James Porter and Rich Hill. My score showed it: up to 113.2 points. That was a 4.4 point improvement in just one week. Solid.

But it would be the best I'd do in the series. The next week was Montara Mountain, and I lost rear-wheel traction twice, unclipping and walking with disastrous results, since I needed to walk all the way to the next flattish section to get back on the bike. Worse was I tried to clip back in a few times and failed, wasting more time. Additionally I just don't climb as fast on rough, loose dirt as I do on the road: I'm too distracted by line and form. My score showed the damage: only 98.6 points.

But I was happy: the climb had revealed a personal weakness, and gave me a goal for next year of improving my speed on the dirt. After all, I had been responsible for putting dirt climbs into the series, with the goal of exposing riders to a broader range of riding.

At the summit I spoke to David Collet, the winner, and he advises keeping my weight back and low on these sections. Back keeps the traction on the rear wheel, low keeps the center of mass low which reduces the likelihood of lifting the front when the front end pitches upward. Additionally, Paul McKenzie emphasized the importance of picking the good line. That I'd understood, but my problem was more what I did when I missed the optimal line. I tended to focus on that fact, rather than deal with the line I had. Indeed, I went with Cara to China Camp the next day to work more on my mountain biking, then the following day rode the mountain bike to work via Caltrain (where my rear shifter cap was knocked off by someone stacking bikes on the bike car, dammit). At work I worked on doing tight turns, as I need to learn to ride switchbacks with confidence. I will improve my mountain biking. It is a moral imperative.

With my two volunteer credits, I needed 3 "real" scores to get the five qualifying scores I'd need to place well in the series. At the end of week 8, Montara, I was in 20th place with, at that point, my two scores counting from Patterson Pass and Lomas, but Montara getting discarded. After Hamilton, which was today, I'd get that third score counted, so I wanted to do substantially better than I had at Montara. If I didn't ride at all Montara would have been promoted to a scoring week.

So Montara was Saturday, Sunday I did an excellent 8-km run (fairly slow but my longest of 3 real runs since my injury) and then did the China Camp ride with Cara, Monday I worked skill on the mountain bike, then Tuesday was an epic SF2G commute down the coast to wish riding buddy Daniel Chao a farewell to his commute down to the peninsula (he's starting work in San Francisco). So it was a solid block of riding. Wednesday, the day before Thanksgiving, I rode from Palo Alto to Mountain View in the morning, then went to a yoga class @ Yoga Tree in San Francisco that evening. It wasn't the best taper to Thursday, having done substantial mileage and climbing two days prior, but with Hamilton so long I wanted to acclimate my body to longer efforts, risking some fatigue.

I knew at Hamilton I'd face a challenge in scoring since, with the exception of Lane Parker's century ride, I was short on long rides going in, and Mt Hamilton is 30 km of mostly uphill. It's very easy to bonk there. A classic mistake I make there is to not take calories, and so I went against my normal policy of water-only in my bottles (sugar makes a polybotanical mess) and used some fairly concentrated Hammer Heed. This proved a smart move, as I never bonked on the climb, or even felt serious weakness.

But a bit of sugar water isn't going to overcome a deficiency in training, and my pace was simply slower on the climb than I wanted. Things went a bit south from the start, as I got stuck behind a rider who threw his chain just past the start line and unclipped. I chased back to the leaders, latching on to the tail end of the group, but then a rider two spots ahead of me let a gap open. It's really important on Hamilton to stick with the lead group on the first of the three major climbs which make up the route. I succeeded, the two riders behind me dropped, but then another rider apparently gave up and let a gap open. This one I couldn't close. I just had to dial it back and hope to find others to pace with.

And I did: it wasn't long before I was in a group of 4, and we were working well together. We crested the first climb. But here I failed: I let a gap open on the descent, and the riders behind me bridged up. I just didn't have any punch to follow, and was braking too much into the corners, which can be gravelly on this road. My Enve 250-based front wheel wheel is a bit dicey on descents, and I'm not practiced in descending with carbon rims in any case, and I ended up gapped off at the bottom of this descent and the start of the second climb.

From here my ride was mostly solo, and I ended up the whole of the third climb trailing two other riders who held a 15 second gap which I just couldn't shut down. The group of two became three, and then they opened it up a bit. There was some wind here and it was advantageous to be in a group for when the wind was a head. Fortunately it wasn't always: the road winds up the mountainside in spectacular fashion, the switchbacks providing some tailwind to partially balance the head. I rode a steady, yet unimpressive tempo here, finishing the climb in 27th place, scoring 109.5 points.

That's not terrible, however. Since I'm working on a fitness deficit I had to be happy with the fact I didn't fade too badly on the extraordinarily long, 30 km Mt Hamilton climb. For the San Bruno Hillclimb on 1 Jan, it's actually good to be a bit underprepared for the Low-Keys, then come out with an upward fitness trajectory and top off with some good climbing intensity in the weeks between Thanksgiving and New Years. But that's not going to happen for me, since I travel for work one weekend, and will be traveling to the East Coast for a family obligations in mid-December and again for the week including Christmas. This is a classic problem for me in December: travel is terrible for cycling. When I'm traveling I'll focus more on running. It's not what I want, however, for a confidence-boosting San Bruno result. I'm not complaining: family gets the priority, and these family trips are important to me. But it's just how it is.

So here I am sort of floating in this void. I have only one additional physical therapy session for my injury, then I'm done with that. I'm dedicated to continuing my yoga classes. I'm de-emphasizing the weight room which was a major focus from soon after my injury in June until October. I definitely want to get back to trail-running shape, as it's been way too long since I raced a trail run. So I'll see where I end up. I'm definitely not planning on slacking back and slipping into any sort of sedentary purgatory. I need some sort of competitive goal.

Friday, November 22, 2013

Low-Key hillclimbs consolidated results pages


I am a firm believer that old event results matter, and am always dismayed when I check for results of some past event or race and can't find them. The half-life for old results tends to be around 2 years: typically you can find last year, but go back two years, and it's 50-50. Since a big motivation behind Low-Key Hillclimbs was to show how things can be done better, I've made an effort to keep old results easy to find.

With this in mind, I've long had a vision that results should be in some sort of queryable data base. For example, want to find the best scores for women in the 20+ category? No problem. I can do that: I have command-line tools which allow me to quickly search a CSV file of scores from the entire series history. But to provide an on-line access to that would be nice.

But that would be a lot of work. As an intermediate step, I decided to write Perl code which would generate static HTML of the consolidated results for every climb Low-Key has done. Many climbs have been done only once, for example 5 of this year's climbs were new. Others have a rich history, most notably Mt Hamilton and Montebello, which are ridden every year (except in 1998 when Hamilton was ridden twice, Montebello skipped).

My code was similar, but far simpler, than the code I use to score the series. The increased simplicity was due to the scoring scheme and the lack of the need to calculate team rankings, overall score, most improved rider, etc: just calculate a score for each rider for each week. The scheme I used was a relatively simple one which I've used before: adjust women's time by a factor, find the median adjusted time for all men and women, calculate everyone's scores using that median as a reference for 100 points. This is simple and robust.

Then for each climb I just made a ranking. It's mostly fair, our start lines and finish lines haven't changed much with the notable exceptions of Quimby, which shifted due to sprawl, and Kings Mt Road. For Quimby I assigned the two start lines as separate climbs, but for Kings Mt Rd, the start lines were closer, and 1995 times thus have an advantage versus subsequent years.

A lot of this work was done during a 4 hour 20 minute Caltrain commute where the train was halted due to a down power line. It was a nice focused time to get it done. "A bad commute on the train is better than a good commute in the car", assuming you don't have a deadline.

Then I indulged in a little Javascript to randomize the banner for the page. This took a lot more time than I expected, but it's good to dust off my limited Javascript skills. Here's the result. Low-Key started way before Strava and part of the motivation was to document good times for various climbs. Finally, with results indexed by climb name, mission accomplished. But with Strava's exponential growth, that largely serves that function now.

Next would be cool to make pages for each rider, or better yet, to provide a PHP form which will do the same rather than maintaining static HTML.

Wednesday, November 20, 2013

history of Low-Key Hillclimb banners

I've been organizing the Low-Key Hillclimbs, with one extended break, since 1995, and as a cycling event it has always has always had its existence firmly planted in the internet. It was relatively early in that regard.

Web design hasn't really help up with the times, however. The pages are relatively simple HTML, although I indulged in some JavaScript in 1997, even with on-line ordering for T-shirts. I've only recently started using PHP, and only for Strava API interaction. I want to move toward more PHP in the future, but for now the HTML works fine.

One feature of every year is a banner image. Banner images are rather dated these days, but I still like them. Here's a brief history of the Low-Key Hillclimbs banner image. One note: the 1995-1998 pages were reconstructed, since they had been inadvertently lost. 1995-1997 were regenerated with original graphics, but 1998 was generated fresh in 2008 from 1998 result data. So the 1998 banner image is circa ten years later.

1995: Rendered with a crude X11 paint program, using silouette of Marco Pantani

1996: Bolder font, tightened, but otherwise similar

1997: Intensity was the theme (slight irony), against green background

1998: Original web pages no longer available; this was basically a copy of 2008

2006: The Comic Sans was supposed to represent Low-Key. I alpha-channeled year.

2007: I scripted the year, and changed the text color

2008: Copy of 2007

2009: Another copy of 2007

2010: I graded the text color and reduced opacity on year

2011: New design, using a metallic text tutorial for Gimp

2012: Copy from 2011; I actually coped and pasted 2nd 2

2013: No "3" to copy, so new design: colors more plastic, with nova in background, using Gimp

2014: Fun with Gimp render filters, Mt Hamilton paceline in background, and improved year placement

I am a big fan of compact file size, as I can't expect everyone to have maximum bandwidth 24/7. But of course file size budgets have increased over the years. 1995 was 4-bit GIF mapped to the Netscape Color Cube. By 2014, it's 24-bit color with 8-bit alpha channel. Still, compared to the vast majority of the web, the Low-Key pages are exceptionally compact. This policy paid off with the explosion of mobile device web access. I have no need for mobile versions of the Low-Key pages: they were already mobile-compatible.
banner size vs year

The 2014 design I did yesterday afternoon on my train commute, and finished it off this morning sipping tea (decaf black, mixed with a protein-fiber-vitamin drink mix and a bit of Stevia... yum, yum). Every year I go into it thinking perhaps that year is the last year for Low-Key. Every year needs to have freshness, needs the support of my co-conspirators, and needs to address the key concerns of all involved in things which can be improved. Every year needs to be better than the one before.

Tuesday, November 19, 2013

VAM analysis of climbing Marin Ave in Low-Key Hillclimbs 7X Challenge

Marin Ave isn't like most other climbs. With Marin, it becomes as much a matter of survival as of speed. Speed is desired as much because it ends the suffering sooner as because of the desire for any target time, placing, or Low-Key Hillclimb points. Yet in the case of Saturday's 7X challenge of course the placing and the points were still important.

A nice thing about metrology data is they tell a rich story if examined closely enough. In this case I didn't have a power meter, my PowerTap too heavy for timed hillclimbs, so I have to rely on other ways to judge my effort. On a climb this steep, VAM is a nice proxy for power, so I use that to judge my pacing.

VAM extracted by numerically differentiating measured altitude with respect to time is inherently noisy, especially on a Garmin Edge 500 where altitude is reported with 1-meter resolution. So to get meaningful numbers I convolved the result with a Gaussian of sigma 3 seconds. This smooths the VAM to something which works fairly well. A longer time constant would lose any resolution of the plateaus which are the ten cross streets delineating the 11 blocks which comprise Marin Ave.

Here's the profile, in all of its nastiness:


Of the first eight blocks, only one, the block to Spruce, is really steep. Marin Ave's heart lays at the end. In a way the first eight blocks are there just to prepare you for that. I knew this, having ridden Euclid twice before, and having studied the profile before that.

WIth this in mind, here's the VAM data from my ride on Saturday, where the data end where the final checkpoint is triggered, which is approximately 5 vertical meters below the finish (in order to provide a buffer for GPS error).

Dan Connelly

I hit the first block, to Shattuck, fairly hard. My legs felt good despite having made a maximal effort up Lomas Cantadas ending less than an hour earlier. But then I settled into a more sustainable effort. I was holding back, waiting, keeping something in reserve for what I knew to be coming.

On the steep block to Spruce my VAM naturally increased, as I tried to keep a reasonable cadence in what was already my lowest gear, 34-27. From here it was 3 more blocks to Euclid. I kept the gear spinning. I was gaining on the tandem a few blocks ahead. I wanted to make good time even if I was holding a little bit back to survive my approaching fate.

But when I hit Euclid, reality was still a sobering blow. You can see my VAM drop dramatically here as I first freewheeled, then softpedaled across the road. The grim inevitability of the pain which was to follow hit home. All I could do is postpone my fate, even if for only a small number of seconds.

Then I was there: on the brutal slopes of the first of the final three blocks, to Hilldale. My VAM jumped here simply because I had no other choice. To keep turning the pedals at a reasonable cadence meant my vertical speed had to increase.

I hit the next block without much hesitation. Again, I kept the pedals turning. Still brutal, it's slightly less steep than the preceding block, so my survival-mode VAM dropped a bit.

My legs were pretty much empty now, yet I had one block left. Again, I paused slightly at the cross-street, collecting the will for the final wall to freedom. My legs hurt, and they would soon hurt more, but only for a brief time. Then I would be done.

The last block I went at my maximum: the tandem was right there, having finished soon before. But I was near empty, I had nothing left. My VAM increased but not by much more than my cadence demanded.

So there it was. Of the 9 riders in my division (human-powered male solo riders) I had the third best time, a personal record of three tries. Success. Yet it's interesting to compare my effort to that of the fastest rider in the division, David Collet.

Dave Collet His effort follows some similar patterns to mine. But his VAM on blocks during the first 8 blocks was more consistent than mine. He was less conservative, pushing himself harder on the less steep blocks, saving himself less. At Euclid, the massive drop in VAM in which I indulged to prepare mentally and physically for the final three blocks isn't seen in his data. He crossed Euclid with relatively little delay, throwing himself immediately into the final three blocks. The same was true on Keeler: no pause, just the beginning of an impressive sprint to Grizzly Peak.

The crux of Main is the final three blocks which follow Euclid. These blocks are occluded from view by Euclid's width. All that's visible is the stop sign at Euclid's leading edge, and only when you crest this rise does the brazen monstrosity of the final three blocks confront you. I'd ridden Marin twice before, and studied the profile before that, so I knew what was coming. Yet knowing and experiencing aren't the same thing, and it intimidates me every time.

There's no way I'm going to match David's time, but it's clear from his data a bit less mental intimidation, a bit more confidence, would have improved my pacing. But easier said than done. There's not many riders who aren't scared of the challenge Marin provides. Such grades, if you can find them on urban roads, are usually found for one, two, or maybe three blocks. Eleven consecutive blocks of this is hard to grasp. But I hope to have another shot at the hill when I'm fitter than I am now, just getting my fitness back after a prolonged focus on rehabbing from my June crash.

Monday, November 18, 2013

Low-Key Hillclimbs week 7x: timing Marin Ave with GPS

Saturday was a double event of sorts for Low-Key Hillclimbs. We had the standard climb, up Lomas Cantadas in the Berkeley Hills, but we combined that with a bonus event, to do Lomas and Marin Ave, in that order, in the same day. We called it the 7X Challenge.

The climb of Lomas Cantadas was fun. I felt stronger than I had the week before, at Patterson Pass. The pace was very quick at the start, requiring a level of explosiveness I simply do not have now or maybe ever, and I drifted back. This cost me a bit on the short descent, where I was in slower traffic than the leaders, but I did well on the final steepest portion, passing riders who suffered from having stuck closer to the leaders in the early going. Among the riders without electric assist, I was 9th, a very good result for me this year, given my ongoing physical therapy to recover from my June crash and injury.

I helped with the finish line crew to get the numbers of riders finishing after me, then headed over to the parking lot near Grizzly Peak Boulevard where Cara had brownies and gingerbread in addition to water, juice, and other goodies. Paul McKenzie and Paul Chuck were there on their tandem, and they led a group to Marin Ave, to complete the 7X challenge.

Marin Ave on tired legs is a memorable experience. The first 8 blocks wear you down so when you crest Euclid, revealing the final three, steepest blocks ahead, it makes a rapid impression. But I survived these three blocks, ending up 4th out of 9 among men in the challenge standings (as I write this: riders may still upload their data until Monday evening). In addition there was one woman, one hybrid-electric bike, and, remarkably, Paul and Paul's tandem.

The timing of the event, not surprisingly, didn't go as smoothly as I'd hoped. It was better than Portola Valley Hills, for sure, but part of that was because there were so many fewer riders. The GPS timing was applied to both Lomas Cantadas and Marin Ave, the former to allow those who didn't do the Low-Key climb to still participate in the 7X Challenge. I'll look here at Marin Ave.

Here's the x-y position (the start line of Lomas is the origin) for all of the riders who did the Challenge course. Most of the data are excellent, but there are three clear outliers:

Marin positions

I plot only the data between the triggering of the start line at the traffic circle at the bottom of the climb and the triggering of the finish at the top of the climb. The obvious culprits are 409 (Edge 500), 405 (Edge 500), and 108 (Edge 800). This wasn't completely to the script that Edge 500's cause all the trouble, but they were still 2/3. In the case of 405 and 108, the data recovered just in time to trigger the finish line. In the case of 409 I had to apply a manual finish line move to have him trigger it (I could also have defined a manual trigger time for the rider: that's a code feature I want to add, since it would be faster than moving the line). I did that by referring to his altitude. I could also have looked at his speed, but the top was fairly obvious from altitude.

This brings up the question whether altitude provides a way to automatically trigger timing events in GPS-timed competitions. For example, if position is poor, but altitude is accurate, and I know the finishing altitude of a climb, then I can trigger the timer when the rider approaches that altitude (leaving some margin for error).

To investigate this, I plotted altitude versus distance for each of the riders. In this case, the distance starts when the rider first triggers the start of the climb. Two riders returned to the start and retriggered it, one after riding partway up Marin, the other up an alternate street. The timing code handles this fine: the time is taken from the last time the start line is crossed. But this isn't important to the purpose here: what's of interest is the start and finish altitude, and if the rider's altitude changes monotonically from start to finish.

Marin altitudes

The answer: clearly not. And interestingly it's some of the same suspects as last time: 405 (Edge 500) and 108 (Edge 800) have the worst altitude data. 409's profile is poor, but that's perhaps because distance is wrong: the altitude increases monotonically between limits consistent with the other riders.

So what we have is there's a good chance poor position is associated with poor altitude. Since the Garmin units use GPS-corrected barometric altimetry, that's not too surprising. If you're relying on GPS to calibrate the barometer, and the GPS is out on vacation, you're using an unreliable reference. Altitude can't naively be used as a backup for poor position data. Good altitude and good position go hand-in-hand.

Sunday, November 17, 2013

Low-Key scoring and X-weeks

Low-Key scoring got complicated when we started balancing the contributions from each week. The results from one week can affect the results of other weeks. This is fine. There's several goals in the scoring:

  1. the average of all rider scores should be 100.
  2. rider scores should be as consistent as possible week-to-week
  3. if I plot the logarithm of scores versus the logarithm of times in a given week, I get a straight line, the average slope for all weeks being one.

A trivial example for this might be the following:

Suppose rider A does climb 1 and gets a time. He's the only rider in climb 1. Climb 1 has been the only climb. He gets 100 points, consistent with the first goal.

Now rider A does climb 2 and gets a time. Again he's the only rider, but now there's been two climbs. He gets scores of 100 and 100. This is consistent with goals 1 and 2.

But suppose now I realize there was also a rider B in week 2. Rider B was 20% faster than rider A. Using the third goal, this means rider B should score 20% more than rider A in this week.

So what do I do? I could assign rider A scores of 100 and 100, as before, and give rider B a score of 120. But this would be inconsistent with the first goal. I want the average to be 100. The two scores for rider A are x. The score for rider y is 1.2 x. I then get the following algebraic equation:

x + x + 1.2x = 300

The solution is rider A scores 93.75 for weeks 1 and 2, but rider B's score in week 2 is 112.5.

However, here's where I get into a problem when I use "X-weeks". X-weeks are climbs which are scored like regular climbs, but don't affect the regular series scores. We had examples in the 1990's, but the first "X-week" in the "modern era" with this sort of scoring scheme was yesterday: The Lomas Cantadas - Marin Ave double.

Suppose the second week was an X week. The score from the first week was affected by what happened in the X-week. I can't let week 1 scores change due to the presence of week 2.

So if week 2 is an X week, the scores should be 100, 100, and 120, as I initially calculated. The first goal, that the average score should be 100, and indeed the third goal, that the average slope of scores versus time on a log-log basis should be one, should exclude X weeks. I will still calculate a slope for the X week, consistent with the second goal (rider scores should be as consistent as possible), in a more complicated case (in this trivial case I don't have enough scores to do so). But the result shouldn't feed into a series average.

This problem only manifested itself when I calculated the week 7x scores. I saw scores dropped for the week 7 climb, which was just Lomas Cantadas. That wasn't desirable.

The problem obviously gets more complicated when you have up to 10 sets of scores for on order 100 riders per week. I end up calculating statistical weights based on the number of riders per week, and the number of climbs per rider. I'm not sure the method I use formally optimizes to these stated goals. But in testing, it does much better than the previous, far simpler algorithm. I described some of this testing back in 2011.

But the "X-week" model may still have a few surprises in store in terms of unintended consequences. Hopefully I can isolate any before the end of the series.

Friday, November 15, 2013

polyline checkpoint enhancement for GPS timing during Low-Key Hillclimbs

As I initially described here, I have been developing an event model for GPS data for the Low-Key Hillclimbs. This allow us to do things which weren't possible before:

  1. dirt climbs: 2012 and 2013, where it's better to let riders do it on their own
  2. short-hills routes, where there's too many time points for practical hand-timing
  3. bonus climbs, supplementing the standard "event", in which riders get a chance to experience more challenges

A limitation of the model has been checkpoints are defined as fixed line segments. This provides a much better solution to event applications than does the Strava timing algorithm, which is optimized for users who within a few seconds define an arbitrary, abstract "segment" and the code is left to match rider data to the segment without much additional information. My model is set up for a course designer who is willing to carefully optimize the placement of a series of checkpoints, to improve timing accuracy and to reduce sensitivity to GPS errors and rider navigational choices consistent with the course goals. Strava's present algorithm will never serve the need of event organizers who want to verify course completions, potentially with time limits, and optionally timing riders over various portions: in events, there's simply too little margin for error. However, the simple model of a checkpoint as a single line segment can be limiting.

Checkpoints can serve two purposes:

  1. to provide optional split times
  2. to verify completion of a course, for example that the rider didn't take a short-cut

For split times, it makes sense to optimize the line strictly for the purposes of timing. If GPS data is flaky, and position errors are large, or GPS drops out during the ride, you don't want to assign split times to that rider associated with that checkpoint. But if the split times are just supplementary to the overall time, that's fine.

Additionally, for timing, you probably want the line to cross the road at a perpendicular angle. This way if the rider is to the left or right, the rider gains no advantage or disadvantage on splits associated with that line. This is basic stuff in start-finish line placement.

But if the point is just to verify the rider passed, there's no reason to worry about such things. The line can have generous width, angled to best avoid the roads presenting potential short-cuts. But with course verification, GPS data drops may still be an issue. And a single straight line may not be the best shape to catch the rider moving along the desired path.

To address this I extended the model to include polylines.

In the old code, a checkpoint was characterized by a line, which included a left and right boundary. The line needed to be crossed with the left boundary on the left, the right boundary on the right. It was encoded as a center point and a right point, with the left point a reflection of the right through the center. There was also an optional distance parameter, to allow tuning of the distance between the center point and the left and right boundaries, retaining the distance. This was implemented to facilitate extending the line if in practice GPS errors turned out to be larger than expected.

With polylines, checkpoints are instead represented by a list of such lines. In every preceding case, the list was length one. But the list could be arbitrary length. The code then goes through the list and checks in order if any of the lines is crossed, again with its right boundary on the right and left boundary on the left. If any is crossed by the path between two points in the user trajectory, the checkpoint is considered triggered

Polylines represent a surprisingly broad range of applications. The one which inspired their implementation is a series of sequential checkpoints along an unambiguous section of the route the rider must traverse. It's not important which of the checkpoints is crossed as long as at least one of the checkpoints is crossed. If GPS signal integrity is unreliable, and the signal might drop or large position errors might occur, this application can be used to verify course completion. Obviously this wouldn't be best for timing, since the time could be taken to any of a series of checkpoints which lie at different distances. If the user went through more than one of these sequential checkpoints, going through following lines would simply retrigger the same checkpoint. This would have relevance only if there was a time budget to either the next or the prior checkpoint.

But there's other possibilities. Another would be a checkpoint which consists of what is effectively a curved line. Segments could be connected, the left boundary of one matching the right boundary of the next. While the data representation I'm using doesn't easily facilitate this, it would be a simple enhancement to support it so in the course definition phase only the series of vertex points would need to be specified.

An application of this would be a course where the goal was to hit a landmark, from any direction, then move to an additional landmark. I could construct a polygon around the landmark consisting of three more more sides. The user would need to enter, or optionally leave this region to trigger the checkpoint. If the points were arranged clockwise looking down, each segment ordered left then right, the checkpoint would be triggered upon leaving, while if they were arranged counterclockwise, the checkpoint would be triggered upon entering.

Another would be a checkpoint where I wanted to avoid potential alternate paths, and space was tight. Consider roads A, B, and C. I want to make sure the rider is on road B which is between A and C. However, from a desired checkpoint the direction of minimum distance to A is in a different direction than the direction of minimum distance to C. I might put a two-part polyline, from between A and B, to the point on B, to between B and C. Or I could make it a 3-part line with a short segment perpendicular to road B. The idea is to shape the net to catch the rider to maximize the chance of catching the rider without catching riders on alternate paths.

Another application is a bidirectional checkpoint. Imagine a course with an out-and-back, where the rider must circle a loop at the turnaround. Perhaps I don't care if the loop is made with a left turn or right turn. I could put a 2-segment checkpoint at he apex of the loop, one for clockwise riders, the other, identical except the left and right boundaries are swapped, for counterclockwise riders.

Another application might be routes with time limits (time budgets) for road segments where the rider might spend time at a rest stop. Suppose I have a route from A to B to C, and there is a 1 hour limit from A to B, and another 1-hour limit from B to C. A rider spends 10 minutes at checkpoint B. If the rider were to take 45 minutes to go from A to B, then spend 10 minutes at B, then 55 minutes from B to C, then the rider would rather have the resting time at B assigned to the A-B portion. That would provide for 55 minutes against a 1-hour budget for both A-B and B-C. On the other hand, if the resting time were credited to the B-C portion, that would result in 45 and 65 minutes, the 65 minutes going over the 60 minute time budget, and there would be a 5-minute penalty against overall time. To do this, I would put in a polyline segment, one before the rest stop, the other after. Then riders would trigger it twice, and the code would pick the one which resulted in a minimum net time for the rider, as I described in my blog post on recursive course time determination.

So this extension of the model, from checkpoints consisting of a single line segment with left and right boundaries, to multiple line segments each with its own left and right boundary where the rider triggers the checkpoint by crossing any of them, has considerable power, especially when used in conjunction with the flexible, recursive course timing algorithm I described previously.

It's still somewhat limited, however. I require checkpoints themselves to be crossed in order. I still have no way to say "checkpoints A and B must each be crossed but in either order". For example, it's popular in alleycat races to have riders need to visit a series of landmarks but optimizing the order is part of the competition. While the code could trivially be modified to support this, combining this functionality with the existing one in an elegant fashion would be additional work. A slight generalization of this idea would be "N checkpoints, of which M must be crossed, where 0 < M ≤ N". For example, I might want to define a series of checkpoints along a route with unreliable GPS, but make sure the rider hit at least half of them. This comes closer to the Strava path matching algorithm.

Okay, I'd better stop now, otherwise I'm going to want to overhaul my code again, and it's already working in advance of tomorrow's bonus route of Lomas Cantadas and Marin Ave in the Berkeley Hills. I'm excited to see how it goes.

Sunday, November 10, 2013

Low-Key Patterson Pass: small groups and the prisoner's dilemma

The prisoner's dilemma is a description of a problem where you have two suspects are captured, accused of committing a crime, and are isolated in separate cells. If either admits to the crime while the other does not, the prisoner admitting to the crime is set free, the other given the most severe punishment (10 years in prison). If they both confess, they are given a light, 2 year sentence. If neither confess, they are held in prison for one year, but eventually freed for lack of evidence.

So if you're one of the prisoners, what do you do?

If they could collaborate, then the best approach would be for neither to confess. They'd esch serve a year in prison, which isn't great, but overall they'd serve only two years. That's much better than the alternates.

But they're isolated, so they can't collaborate. For each prisoner, what the other prisoner does is beyond their control. If the other prisoner confesses, then he is better off confessing as well, getting a 2-year sentence. If he does not, he'll get the maximum of ten years. On the other hand, if the other prisoner does not confess, then confessing means walking free, while not confessing means a year in prison.

So the best result for the group is cooperation. But if individuals act in their own selfish interest, then there will be no cooperation, and the net result is worse.

This is what happened in the group 2 small groups start at Patterson Pass yesterday. Groups were ordered by speed, based on prior scores or, in the case of a few brand-new riders, by considering results in other races, if any. The groups were thus fairly well matched within the group, but were still competing against each other. It was a mixture, therefore, of competing against the riders within your group and cooperating with the riders within your group.

The best overall result for the group was that everyone contribute on the early, relatively flat portion of the course. And by "contribute" I mean spend time at the front at a level of effort which will cause some fatigue, causing some loss of speed on the steep portion, but just a little. The payback in following the draft of other riders within the group, each of them also riding at a fatiguing pace when at the front, would more than compensate the loss.

However, without any way to enforce global cooperation, for each rider a better scenario is that everyone else does fatiguing pulls at the front, while that individual rider sits in and rests. Every rider in the group would prefer this to occur, so for every rider within the group the incentive is to sit in and rest, or if at the front to take a brief, low-power, non-fatiguing pull.

In group 1, one rider, Nils, hammers most of the way himself. This was good for the group, since Nils is freakin' strong on the flats, but it hurt Nils' result.

In group 3, there was a strong tandem with Paul McKenzie and Paul Chuck (this is Low-Key, so we allow all sorts of bikes to ride together). Tandems are well known for being strong on the flats, and in this case the tandem led the way along the flattish section, everyone else within the group benefitting.

But in group 2, we had no tandem, and we didn't have Nils. It was going to be up to each rider to contribute, and not enough did. I took the first pull, from the start line, and one other. That would have been more than enough given the length of the opening section and the number of riders (10) in the group.

But too many riders weren't working. They were playing to the prisoner's dilemma. As a result, group 2, which should clearly have been faster than group 3, lost substantial time to that group here, and of course we lost even more time to group 1. Our scores suffered as a result.

This is shown in the following plot. The plot uses only male solo scores, for consistency. I have two curves: the blue curve is the rider's best score in the most recent year for which that rider has a score, with older scores depreciated 1%/year. This is what I used for group assignments. The other curve is the average score for riders in the group on Patterson Pass.

group performance

group performance 2

Although group 2 still did better than group 3, the differential between group 2 and their qualifying score is the greatest among all groups. It's clear group 2 could have done better overall, even if the "selfish" strategy may have helped some of the individual riders. Group 3, in particular, did well at Patterson due to the hard work of the tandem there. (Note: I fixed this from an initial version which showed group 6 also scored low. In the revision, where I restricted the comparison to riders for whom old scores existed. It's important the same riders contribute to both curves.)

Thanks to Paul McKenzie, here's the average speed of the groups on the first 1.3 miles:


From Paul:

My conclusion from this limited data is that Group 2 was indeed soft pedaling at the beginning, and conversely, Group 4 put in quite a cooperative effort, putting about 24 seconds on Group 2 during the first part of the climb. Those in our group (Group 3) received the benefit of a nice tow to the base leaving them with fresher legs for the climb.

This may seem unfair to members of group 2. But we dug our own graves. A great thing about bike racing is it's multiple facets. It's more than just a physical contest, it's also a mental game. And the prisoner's dilemma is a classic mental game.

By the way, this situation was very similar to handicap racing, where slower riders are given a head start, and the first across the finish line wins. There the penalty is more obvious, however: you can see your competitors up the road, or approaching from behind. Here the results aren't obvious until the math is complete on the start and finish times. But they're just as real.

Friday, November 8, 2013

Letter to Supervisor Cohen on Potrero Streetscaping project

I went to a public meeting on the Potrero Streetscaping project. The principal opposition was from those who fear the loss of parking along this busy, dangerous, high-speed road, which was formally the major through-road along the eastern boundary of the city until that function was taken up by highway 101.

Here's my letter to my supervisor, Malia Cohen, which I hurriedly dashed off this morning before riding to physical therapy:

Supervisor Cohen:

I was at the public meeting last night ont he Potrero Avenue streetscaping.

The core issue is the priority our transit-first city is going to place on private vehicle parking versus MUNI efficiency and pedestrian and cycling safety. MUNI is bogged down in traffic and pedestrians and cyclists are being picked off on our roadways at an appalling rate. It is thus imperative to the quality of life in the city that this project moves forward.

The key requirement is that traffic on Potrero Ave slow down. The median landscaping, by making the road less highway-like, is the best approach to accomplishing that. A bike lane buffer would be nice, but with 50-mph car traffic, cycling will never be safe there. We need to slow down the cars.

Slower cars make traffic move smoother, in any case, and smoother traffic gets people to their destinations safer and quicker.

Some at the meeting prioritized parking over safety and traffic throughput. Indeed, parking creates traffic turbulence, which creates congestion, which slows everyone. So parking on major transportation routes should not be a priority.

The better approach is to reduce the demand for on-street parking. This is done by following the city charter: improve transit, improve conditions for pedestrians and cyclists, and additionally encourage homeowners to scale back the size and number of personal vehicles and to use garage space for its permitted purpose, which is to store vehicles. Storage of household good should be outsourced to storage facilities.

Our land is too precious in this highly valued city for free parking to be a priority. Indeed, cities where parking and wide, fast roads are the priority tend to be low on the liveability index. They destroy neighborhoods and isolate neighborhoods. Potrero Ave is presently a traffic sewer, to be avoided by all who have the choice to do so. It can be so much better. This project is a step in that direction, and should be embraced, even if change is always feared, and always resisted.

Please do the right thing and support the Potrero Streetscaping project.

Tuesday, November 5, 2013

How I voted in Nov 2013 San Francisco Election

Usually I like to post summaries of my views on ballot measured, etc, before elections. After all, if we just vote in silence then we get just one, barely significant vote, but it is in discussion of the issues that voters have their real power. However, this election I slacked off, and I post this after I already voted and the polls have closed.

This was the smallest election I remember, certainly in San Francisco, maybe anywhere. There were no contested races, 4 city ballot measures, and nothing at the state level. Turn-out will be extremely small.

Here's how I voted on the ballot measures:

  1. Prop A: Yes. This is a restriction against tapping into city employee health care accounts for other purposes. Actually I didn't look at the nitty gritty details, and honestly I'm not sure how effective it will be, but it has a lot of support and seems like a good idea.
  2. Prop B: No. A condo development along the waterfront wants an extension of the normal height restriction. I'm a fan of dense development, but I can understand why you'd want to limit heights along the bay, since the waterfront is a popular pedestrian area, and large buildings block views and the sun. The real clincher on this one is the process: I don't want every developer going to the voters to get exemptions from city requirements. Additionally I didn't like the way this measure was marketed: "parks, not parking lots". In addition to their giant condo building they're putting in some grass on land which is presently a parking lot. However, they make it sound like they're turning the whole thing into a park. That's misleading. And this obviously isn't the only development option for the lot.
  3. Prop C: No. Related to B.
  4. Prop D: Yes. This is a popularist "position statement" that San Francisco wants governments to reduce the cost of prescription medications. It's an important issue, so I support this. But it has no power.

That was that. And looking at preliminary results, it looks like my votes mirrored the popular vote. I don't think that's ever happened before.

Saturday, November 2, 2013

GPS accuracy comparison using Portola Valley Low-Key Hillclimb data

As I noted, when dealing with GPS problem cases in the Portola Valley Short-Hills version of the 2013 Low-Key Hillclimbs, I couldn't help but notice every one of the cases I grappled with was an Edge 500. This is anectdotal, so I wanted to take a closer look at the problem.

The initial plan was to scrape the HTML from the Strava pages with a Perl app, since the API doesn't provide computer type, but when this didn't work out for me since Strava requires user authentication to see this info bit I started thinking about PHP options but finally when I couldn't sleep last night I just went to the pages sequentially and transcribed the computer identifier from the browser. Brute force. Not elegant. I feel so dirty.

There were 69 riders @ Portola Valley who each reported the URLs of their Strava records. I then compared these using the root-mean-square average of the distance from the center of the lines the riders triggered the lines (units: meters). The ideal number isn't zero, because my lines are generally in the center of the road and riders are to the right, and in any case there's other sources of error than rider GPS, but "perfect" would probably be 2 meters or so.

Here's the average by computer type:

n rms dl
rms rms dl
Osync Nav2Coach
Forerunner 405
Edge 305
Strava iPhone app
Edge 800
Edge 705
Edge 200
Strava Android App
Edge 510
Edge 500

I am told Scott Byers was using an Osync Nav2Coach, which Strava failed to identify. That unit clearly works extremely well: his score was close to ideal. Indeed, it's a testiment to the superb registration of Google's satellite maps, based on which I placed the lines.

It's not as bad as it looks for Edge 500, though. There's plenty of decent results from Edge 500. It's just it has a virtual monopoly on the really bad results.... curiously along with one screwed-up Joaquin from an Edge 510.

Detailed results (hopefully this renders properly) with numbers linked to Strava activities:

13262.74391Jeff ShuteEdge 305
2492.85231David ColletStrava iPhone app
3372.90553Scott ByerOsync Nav2Coach
4583.11199Andy CrewsEdge 705
51323.17032Stefano ProfumoForerunner 405
61563.22356Todd StudenickaStrava iPhone app
7233.24592Daniel AminzadeEdge 800
82043.34927Bryn DoleEdge 510
94073.40899Brandon IlesEdge 500
10653.41488Giles DouglasEdge 800
112123.75249Peter C IngramStrava iPhone app
121253.90218Frank PaysenStrava Android App
13833.9244Rich HillEdge 500
14534.12421Tracy ColwellStrava iPhone app
152034.24395Kevin ColagiovanniEdge 500
16124.29885Will von KaenelEdge 800
174114.32206Lucas PereiraEdge 705
184124.32909Kieran SherlockEdge 500
191054.59216Doug MacPhersonEdge 305
204044.67041Heidi FraserEdge 500
214085.10658Tom K.Edge 510
221525.14333Daryl SpanoEdge 800
233275.26018Brandon SmithEdge 510
241505.27501Gregory P. SmithStrava Android App
254135.36954Liam SherlockEdge 705
264145.59722Tim SullivanEdge 500
274155.68787Jeff WeitzmanEdge 800
282305.8452Kris McQueenEdge 500
291715.94689Phil LovaglioEdge 500
304026.17513Chris EvansEdge 510
31486.20068John ClarkeEdge 510
321476.41201Marty ScottEdge 200
334016.42501Gino CetaniEdge 200
343166.89468Bogdan MarianEdge 510
35716.96707Stephen FongEdge 500
361667.1123William YeeEdge 510
371357.35438Mihai R.Edge 500
382077.46039Robert EasleyEdge 800
39958.01097Mark KingEdge 500
40278.66326Kate BergeronEdge 800
412238.72471Eva SilversteinEdge 500
424108.8267Paul McKenzieEdge 800
434038.96959Scott FrakeEdge 500
44358.97069Sugar BrownEdge 500
45629.02079Mike DavisMobile
4613311.6204Alec ProudfootStrava Android App
471411.7634Rich McLovin BrownEdge 500
4840612.9423Martin HylandStrava iPhone app
4932813.2219Ray SmithEdge 500
5016013.2689Luis ValenteEdge 500
5115113.9149Kevin M. SmithEdge 500
5230414.4409Paul CothenetEdge 500
533116.0769Blue BrownEdge 200
5412616.2337Lisa PenzelEdge 705
5516116.307Greg WatsonEdge 800
5611417.2566Shahram MoatazediEdge 500
577918.3404Bill HarkolaStrava Android App
587319.1305Chris FurgiueleEdge 500
5930119.4436Amy BruskiEdge 500
6030020.7875Billy Bob BrownEdge 500
613221.6406Haba?ero BrownEdge 500
6240030.3386Michael AndaloraEdge 500
6340549.0466Bruce GardnerEdge 500
649850.2294Michael KowalchukEdge 510
6540954.9151Bill LaddishEdge 500
66122109.659Bart NiechwiejEdge 500
67209146.149Janet GardnerEdge 500
68318186.928Trish PachecoEdge 500
69130233.005Mark PowersEdge 500

So 11 of the worst 12 are Edge 500's. In contrast only 1 of the best 12 are Edge 500's.

31 of 69 are Edge 500's, so the probability of N out of 12 being Edge 500's, by luck alone, are (using the binomial distribution; Poisson statistics aren't good enough for Low-Key):


So the probability of, with luck alone, of no more than 1 in the first 12 being Edge 500 would be 2.4%. The probability of at least 11 of the final 12 being Edge 500 is 0.44%. The combined probability of both of these occurring is 0.011%.

My pick of the number 12 was a biased pick so this isn't really a fair comparison. But it's fairly clear the Edge 500 is particular prone to position error. This is perhaps not representative of new Edge 500's.

The Edge 500 was the most popular computer with 31. The Edge 800 was second, with 9. The third most popular was the Edge 510, with 8. If I do a ranking of all of the results, considering only Edge 500 and Edge 800, there are 40 total. In that ranking the Edge 800's rank 1, 3, 6, 9, 11, 16, 18, 20, and 28. So in that ranking, of the top 20 computers, 8 are Edge 800 and 12 are Edge 500. Of the bottom 20 computers 19 are Edge 500 and 1 is Edge 800.

Suppose I distribute 9 Edge 800's at random among 40 ranked slots. What's the probability at most 1 would be in the 20 lowest ranking slots (and at least 8 in the highest 20 ranking slots)? The number of ways to distribute 0 in 20 and 9 in 20 is 167960. The number of ways to distribute 1 in 20 and 8 in 20 is 2519400. So the number of ways to do either of these is the sum: 2687360. The number of ways to distribute 9 in 40 is 273438880 . The ratio is 0.983%. So the chance of this happening at random is 0.983%. This strongly suggests the Edge 800 is more accurate on average than the Edge 500. However, you can find plenty of good Edge 500 results.

So I establish the Edge 800 is likely better than the Edge 500. Is it better or worse than the Edge 510? 17 of the computers were either Edge 800 or Edge 510. OF those, the Edge 510s ranked 2, 5, 7, 9, 10, 11, 12, and 17. The Edge 800's ranked 1, 3, 4, 6, 8, 13, 14, 15, and 16. The Edge 800 did slightly better but it's too close to conclude anything from this.

There were 6 different Edge units at the Low-Key. There were 5 iPhones. The iPhones did better than 5 of the 6 Edge units; the 2 Edge 305's did better than the iPhone. Between the Edge units and the iPhones, there were 62 activities. The 5 iPhone activities ranked 2, 4, 9, 11, and 42 of 62. So of the top 11, the there were 7 Edges versus 4 iPhone apps. Of the bottom 51 there were 50 Edges and 1 iPhone apps. I won't calculate the probability of this occurring by chance: it's small.

It's interesting, because you'd expect a phone carelessly shoved into a pocket would be inferior to a specifically designed head unit mounted lovingly on the handlebars. On the other hand, the phones have two advantages. One is they are large. Larger = more room for an antenna. The first iPhone was infamous for its poor GPS antenna. I am told the antenna placement in the iPhone was late in the design process, so it was made to fit in available space, rather than being placed early in the process for better optimization. But iPhone users tend to upgrade their hardware, and I doubt there were any early-generation iPhones represented here. The other advantage phones have is they can access the cell towers and use those to help with position determination. Even if no GPS satellites are available, if the phone has access to at least 3 cell towers it can get a position fix. I don't know how much power the phones versus the Edge units are willing to devote to the GPS circuits.

Comparing the phones, the iPhone did a bit better than the Android, but I am reluctant to draw too many conclusions since Android runs on so many different hardware designs.

So lots of interesting stuff here. The conclusion is among the Edge units, the 500 has the most trouble. The 800 is clearly better than the 500 with high probability, and the 800 and 510 are close. By inference the 510 is better than the 500. The iPhone app does well, even in comparison to the Edge units. And older Edge models (the 305 and 705) seem to do about as well as the newer ones. There were no Edge 810's in the mix.

Friday, November 1, 2013

Low-Key Hillclimbs: trends in rider turn-out

As we head into week 5 of the 2013 Low-Key Hillclimbs, the trend has been unambiguous: despite excellent weather, rider counts are down since last year. The climbs are just as good as ever, although perhaps so far on the challenging side. Still, comparing the same climb year to year the conclusion is the same. And with SRAM leading the way first with compact drivetrains and then with wide-range rear cassettes, riders on "racing bikes" have access to lower gears than ever before, making the steep roads less intimidating.

I plot the trend here. 1995-1997 it became more popular and then peaked, dropping off in 1998 when the series took a break. It came back in 2006 and had to rebuild a following almost from scratch. 2006-2010 There's a clear peak 2006-2009 was a period of rapid growth, but then it saturated, with a clear drop-off in 2012 which has accelerated this year.


One hit for 2012-2013 has been the "GPS-timed climbs." These have a lower turn-out than the group events. I understand that, but the GPS timing lets us do climbs which would otherwise be out of reach. And total numbers have bever been the primary goal. For example, if I do a GPS timed event like Portola Valley Hills with 69 riders instead of for example Page Mill Road which might have gotten 120, that's 51 riders less over 4 weeks so far which is 13 riders per week hit on the average. But still that would take 2013 only from 86 to 99.

Honestly the smaller numbers are a bit easier to handle, so I'm not complaining. Although of course one wants something on which puts in so much time to be popular. We've gotten plenty of positive feedback, so that leads me to believe it's due to general trends in cycling, with newer riders more attracted to cyclocross in fall, a sport which has grown enormously in popularity the past ten years.

The series won't go on forever, of course. When it's done I'm sure we'll look back to 2013 as a good year.