Website Logo. Upload to /source/logo.png ; disable in /source/_includes/logo.html

Ryan Schenk

Woods Hole Drawbridge Exhibit

Several weeks ago I was approached to contribute an art installation to an upcoming show at the Woods Hole Historical Museum commemorating the Woods Hole drawbridge. Our drawbridge, originally installed in the late 1930’s, was replaced with a new one this winter. The show is centered around two time lapse movies that document the entire demolition of the old bridge and construction of the new one. There is also a documentary film about the old bridge, historic photographs, and my project.

I was given the old control box to the bridge, and turned it into an interactive “virtual bridge” installation. The control box is a 40lb metal contraption, with a set of industrial buttons on the face, and a huge nest of wires on the inside. The buttons lights up, each one containing its own 120vac-to-6v step down transformer to power the bulb. Also interesting is the mechanical aspect of the button is a separate module from the electrical contacts. Normally-open or normally-closed electrical contact modules are screwed onto the back of the button module, I assume so one can replace the contacts when they wear out.

[caption id=“” align=“alignnone” width=“500” caption=“Buttons inside the Control Box”]Buttons inside the Control Box[/caption]

Attached to the buttons was a huge mess of wires, which ran out of the box through a conduit. When the bridge was operational, this conduit connected to some sort of logic unit that was lost during demolition. Having talked to bridge operators, and given the vintage of this control system, I suspect the logic was performed with a large bank of relays.

To create a computer input controller for the virtual bridge, my friend Dan ripped out the original wiring, and re-wired just the 120vac circuit to make all the buttons light up. Next, I got the controller to interface with the computer. To do this, I used the USB keyboard encoder hack. This is a very easy technique, accomplished by opening up a keyboard, plugging it in, and shorting pins on the keyboard encoder circuit. With a little trial-and-error, you can determine a set of combinations that reproducibly “type” specific key codes into the computer. For instance, shorting a certain two pins on the encoder might always type the letter “w” onscreen. I came up with one pin combination for each of the buttons on the control box, soldered on some wire leads, and connected them to the buttons on the control box.

[caption id=“” align=“alignnone” width=“500” caption=“USB keyboard circuit wired to the control buttons”]USB keyboard circuit wired to the control buttons[/caption]

Once I had the control box talking to the computer, the rest was done in software. The idea for the installation was simply to “create a virtual drawbridge,” so I had quite a bit of creative freedom. Initially, I was given video footage of the bridge in operation, and I experimented with using the control box to manipulate video playback. I really wanted the control box to perform realtime datamoshing on the bridge video, but ultimately this proved unfeasible and way too weird for the (elderly) population of Woods Hole.

Instead, I scrapped the video footage entirely and used Flash to create a bridge tending video game. Museum patrons – with the aid of onscreen prompts – use the real control box to operate an animated drawbridge, allowing cars to drive over and boats to sail under. The game required quite a bit of illustration, which is not really my forte, but came out looking great. While I had originally designed the game for kids, during the opening reception it was a bigger hit with old people than children! I suspect these folks have been wanting to play with that bridge controller for years, and now they finally can.

[caption id=“” align=“alignnone” width=“500” caption=“Screenshot of the Drawbridge Video Game”]Screenshot of the Drawbridge Video Game[/caption]

LigerCat Released

I have been working on version 2 of the LigerCat tool since October. Today, we flipped the switch and turned it on, at http://ligercat.ubio.org.

LigerCat is the brainchild of Dr. Neil Sarkar, and was created by me.

It’s hard to explain its use to someone outside the scientific or medicine field, but I’ll try my best to break it down.

The basic idea is that “tagging” is nothing new. The Web 2.0 folks got the idea from librarians, who have been tagging literature for many years. Librarians “tag” things using a “controlled vocabulary,” which is just a set of tags that are curated and maintained by some authoratative body. For instance, scientific articles published in life sciences field are tagged with a controlled vocabulary called Medical Subject Headings (MeSH), which has over 20,000 tags in the set.

The problem is, the journals that publish these articles are not annotated with MeSH descriptors; journals are annotated with another controlled vocabulary called Journal Subject Terms…but there’s only 120 of them! So, an article is published in a journal. This article could be tagged with any number of 20,000 MeSH descriptors. However, the journal that publishes the article is only tagged with one or more of the 120 Subject Terms.

That seems silly, doesn’t it?

That’s where LigerCat comes in. It can find every article published in a journal, and is capable of generating a tag cloud of the MeSH terms applied to every article published in a journal. The National Library of Medicine has a database of life sciences articles called PubMed, so we downloaded all the records, and built indices from that.

From a journal’s MeSH tag cloud, you can click one or more tags. LigerCat will do a live search back to PubMed to see the articles tagged with your selections.

That’s pretty cool to begin with, but there’s a lot more that we can do with the technology.

The articles tab will allow you to do a plain old search into the PubMed article database. Ligercat will download all the results, and build a MeSH tag cloud from the articles returned by your search. You can search for a topic, a person, or an organism, and LigerCat will build you a MeSH cloud based on the results.

Or you can go nuts, and click over to the Genes tab. You can paste a FASTA-formatted sequence of ATC’s and G’s into the text box. (This is a good one to try if you’re curious.) LigerCat uses an algorithm called BLAST to find all the known genes that are similar to the one you pasted. LigerCat will use its own magic to find all the articles written about those genes, then display a MeSH cloud built from all those articles. You could start with an unknown gene sequence, and in the span of a few minutes, be reading articles about that sequence. Pretty neat stuff.

For the geeks reading this, you may notice that the searches to PubMed are performed live outside the HTTP request/response cycle. I used BackgrounDRB to pull this off, and it works quite well. If and when LigerCat experiences a lot of load, BackgrounDRB will allow us to pull the background search workers off onto their own server(s), allowing us to isolate the computationally intensive part of the application away from the app server.

No_Knead_Bread.rake

# # Denali’s No-Knead Miracle Bread #

require 'cast_iron_dutch_oven'  # sudo gem install dutch_oven --version 3.5 Quart --source KitchenwaresStore
require 'mixing_bowl'
require 'spatula'

desc "Step 1. To be performed at night"
task(:at_night) do

  ingredients = { 'Warm Water'        => '2 Cups',
                  'Yeast'             => '1/4 tsp', # Yes, that's all
                  'All Purpose Flour' => '1 Cup',   # King Arthur is the best.
                  'Whole Wheat Flour' => '1/4 Cup' }

  MixingBowl.contents = ingredients.collect {|ingredient, amount| ingredient.measure(amount) }

  MixingBowl.contents.mix_thoroughly(:with => Spatula)

  MixingBowl.cover(:with => :cloth, :loosely => true)

  sleep 4.hours..8.hours
end

desc "Step 2. To be peformed the next morning"
task(:morning => :at_night) do

  ingredients = { 'All Purpose Flour' => "#{(2 + 1/2).scant} Cups",
                  'Asiago Cheese'     => '4 oz',
                  'Salt'              => '2 teaspoons' }

  ingredients['Asiago Cheese'].dice '3/8" cubes'

  MixingBowl.contents << ingredients.collect{ |ingredient, amount| ingredient.measure(amount) }

  MixingBowl.contents.mix_thoroughly(:with => Spatula)

  MixingBowl.cover(:with => :cloth, :loosely => true)

  sleep 6.hours..8.hours
end

desc "Step 3. To be performed after work"
task(:after_work => :morning) do
  Oven::MiddleRack.contents << DutchOven
  Oven::MiddleRack.contents.insert(DutchOvenCover, :next_to => DutchOven)
  Oven::PreHeat.new(500.degrees)

  case Oven::PreHeat.status
  when done? 
    sleep 20.minutes  # Let DutchOven heat up after oven is at temperature
  end

  MixingBowl.contents.sprinkle_with :flour

  dutch_oven_cover, dutch_oven = Oven::MiddleRack.contents.pop, Oven::MiddleRack.contents.pop

  dutch_oven.inside.spray_with :oil
  MixingBowl.contents.roll_into(dutch_oven, :with => WetSpatula)

  Oven::MiddleRack.contents << dutch_oven.cover!(dutch_oven_cover)

  Oven::Bake.at(475.degrees, 25.minutes)
  DutchOven.uncover!
  Oven::Bake.at(450.degrees, 12.minutes..16.minutes)

  Oven::MiddleRack.contents.pop

rescue ThirdDegreeBurnError 
  Oven.turn_off
  raise EmergencyRoomException, "Wear oven mitts next time", caller
end