October 2014

Aperture Importer for Lightroom

After Apple announced they will stop developing Aperture, Adobe was nice enough to offer a Lightroom plugin to migrate Aperture libraries to Lightroom. I previously wrote some custom scripts around the Aperture library, and can appreciate how much pain they had to deciper the library Aperture uses to get this plugin done (Hopefully they had some help from Apple). The Aperture libraries aren’t always consistent and can vary depending on how old they are, how many times they crashed, so there were bound to be some bugs in the Aperture Importer plugins.

The Aperture Imporer bugs I ran into were around keywords. There are others posted on the Aperture Imporer page, but I don’t have the ability to test against libraries with those issues. Any of the three keyword options would cause the plugin to fail on line 136 or 158 trying to address kwdInf when it’s null. Here is a diff with the fixes. I don’t want to post the full file due to Adobe’s confidentiality notice on top of the file. If anyone from Adobe reads this, would you consider open sourcing this plugin?

For the best results, I recommend running Aperture Library First Aid on the library before importing it into Lightroom. This can be triggered by holding down the Option+Command keys when launching Aperture. I would shoot straight for the rebuild option. Obviously make sure you have backups and all that.

Second, if you are using the option of Aperture Importer that copies previews of adjusted images, you should consider regenerating some (or all) of the Aperture previews. The default in Aperture is not the highest quality previews, which makes sense when they are used for previews. I changed the settings in Aperture preferences to “Photo Preview: Don’t limit”, and “Photo Preview Quality: 12” (highest setting), and then selected all the images I really cared about and regenerated previews for those. You can do this for all images (select all photos, right click, and Regenerate P), but be prepared to get one huge Aperture library.

September 2014

Starry Skies

Tantalus range near Squamish, BC. © Mayo Jordanov

“Do what you can, with what you have, where you are.” #

— Theodore Roosevelt

July 2014

Plotting non-uniform time data with D3.js

For a typical time-series data, one would use the d3.time.scale scale. This scale, however, does not work for plotting non-uniform time-series data (for eg. market data) where weekend days show as gaps and are undesirable.

d3.time.scale example

The easy way around this is to map weekdays onto a uniform scale and use the linear scale to plot it. There is a great example for this by Mike Bostock in weekday.js gist. Simple tick formatting can be added to show proper dates instead of the weekday numbers:

var dateFormat = d3.time.format('%a %b %d');
xAxis.tickFormat(function (d) { return dateFormat(weekday.invert(d));});
Static tickmarks

So far so good, but now the dynamic tick format that comes with d3.time.scale scale is lost. The easiest way to get this functionality back is to yank the code from d3.time.scale and do some slight adjustments to make it work with our interpretations of days (d3_time_scaleLocalFormat, scale.ticks, and associated functions). These can then be used as follows:


Unfortunately, some these functions can’t be reused, as they are declared as private, and others need slight modifications to cope with weekdays instead of Date objects. For simple one-off use, the above solution is probably good enough, but if you need ease of reuse or have more complex application, it might be easier to wrap this up as a standalone scale.

Finished example

The scale takes a mapping function as a parameter, and produces a scale with dynamic date-based tics like the d3.time.scale scale does.

One addition to Mike’s weekday example was caching. For small data sets it works well, but With a couple of axes, brush, and a few years worth of weekday data, the conversion was getting noticeable.

The final code, including an example, modified weekday.js and the d3.scale.dayselect scale can be found in the Dayselect Scale block (or Gist).

One caveat with this method is when using brush, the extent of the brush is returned as date objects, but they are really integers representing weekdays on the uniform scale. This can be easily fixed by prepending a plus sign (+) before it, or doing a math operation on the values: +brush.extent()[0] or brush.extent()[0] * 1.

May 2014

“There is no problem so bad, that you can't make it worse.” #

— Chris Hadfield (quoting an astronaut saying)

April 2014


Sunrise over Vancouver's north shore. © Mayo Jordanov
January 2014


Cloudy sunset over downtown Vancouver. © Mayo Jordanov
November 2013
September 2013
August 2013

Mayo Jordanov is a computer programmer and enthusiast based out of Vancouver, British Columbia. Mayo is currently working as a programmer for a company specializing in electrical grid optimization solutions. On side, he dabbles with photography, design, servers, and various web technologies.

Comments? Tweet @oyam, or email mayo@… PGP key: 0xDDCAFEE6.

Powered by Mercurial and Hyde static site generator.