31 May 2010

Depends on how you look at it

Tom Malzbender's presentation to the Smithsonian Associates on the Antikythera Mechanism focused on Polynomial Texture Mapping. PTM has its roots in computer graphics techniques for rendering artificial surfaces (in game applications, for instance), but in this case it's used to enhance surface detail of physical artifacts.

The process starts with high-resolution image acquisition from multiple POVs: the object to be imaged is mounted in a domed frame fitted with dozens of digital cameras. (The contraption looks something like the Trinity device, to me.)

Once the images are captured, software apps can manipulate the apparent direction of the light source (to realize the artist's "raking light"), and more astonishingly, the apparent surface characteristics (e.g., reflectivity) of the artifact.

The application of this technology to recovering lost surface detail on chunks of bronze that have been sitting in saltwater for two millennia is a natural. Mazlbender and John Seiradakis report that the metal plates that comprise the Antikythera Mechanism's "user's manual" have revealed an additional 2,200 characters, thanks to PTM techniques.

28 May 2010

Breaking the C-note

And first looks at a prototype XO-3 from Seth Weintraub and Nick Bilton. I like the little key ring thing at the corner, though I suspect that's not its intended purpose.

Plans are for at least one version of the box (how can you call anything that slim a box?) to run Android.

[Nicholas] Negroponte also stressed the importance of the open source nature of the project, pointing out that every aspect of the the project would still be open source. "We're going to go totally open," he said. "In some sense it's the complete opposite of the Amazon bookstore or iTunes, where we'll run anything, including viruses and Flash."


(Weintraub link via The Code Project.)

Make another compartment in the toobox

Colleague Harold passes along a notice about Chrome extensions for web development. Not enough there to move me away from Firefox and Firebug just yet, but it's good to know that there are some options.

In a bind

Yesterday I did some refactoring of the JavaScript that manages jQuery Datepickers and the event handlers attached to them. Several of the modal dialog boxes of the application use the following pattern: a text box that permits direct entry of a date (as 'MM/DD/YY'), a Datepicker tied to the text box that allows the user to point and click at a date, and 3 hidden fields for the month, day, and year portion of the date. It is this set of 3 fields that is persisted.

So we have an event handler that takes care of direct input (hdlChange) and one that takes care of the point-and-click selection (hdlDatePickerSelect). The difficulty I had to overcome was establishing an execution context for the event handlers so that they could access member variables that identified the date being processed (several of the app's modals [managed with a jQuery Dialog] collect 2 or 3 dates).

Another complicating factor was this unfortunate behavior of the Datepicker object: as we use it, the Datepicker's text boxes on each modal must have distinct IDs, even modals that have been closed and destroyed. Hence the variable overlayAffix (we call the modals "overlays" in this app) that is appended to the ID-based selector for the Datepicker.

Anyway, back to the problem of establishing context. The nut of it is passing some sort of extra information to the event handler that identifies the this that you want to use, because the event handler's this is the text box DOM element.

I experimented with jQuery's .bind() method, and that worked just fine for the change handler. (Mike West's article is helpful background.) Using .bind(), you can pass whatever you like into an event handler—say, a pointer to your execution context—and retrieve it through the event object. But, unfortunately, I did not find a way to make this technique work for the select handler. The Datepicker doesn't have a .bind() analogue: rather, the handler is specified as the option onSelect; furthermore, the signature of the handler doesn't include the event (AFAIK).

So I resorted to what I consider trickery, taking advantage of JavaScript's expando properties: I simply attached the execution context as a an additional property of the text box (date control).

Here's the completed script, lightly edited for presentation. Wording note: context in the code below refers to the jQuery DOM context, not the execution context that we've been discussing.



// Helpers for managing a datepicker, the associated text box, and hidden fields.

CLIENT.Utilities.DatePicker = function (context, overlayAffix, dateAffix) {
this.context = context;
this.overlayAffix = overlayAffix; //identifies the overlay we're on (e.g., 'GeneralJournal')
this.dateAffix = dateAffix; //identifies the date (e.g., 'invoice')
this.datePickerSelector = '#' + dateAffix + 'Date' + overlayAffix;
this.monthSelector = '#' + dateAffix + 'Month';
this.daySelector = '#' + dateAffix + 'Day';
this.yearSelector = '#' + dateAffix + 'Year';

this.setDate = function (date) {
try {
$(this.monthSelector, this.context).val(date.getMonth() + 1).change();
$(this.daySelector, this.context).val(date.getDate()).change();
$(this.yearSelector, this.context).val(date.getFullYear()).change();
} catch (e) {
CLIENT.Utilities.postWarnMessage('', 'DatePicker.js setDate()', e);
}
};

this.clearDate = function () {
try {
$(this.monthSelector, this.context).val(0).change();
$(this.daySelector, this.context).val(0).change();
$(this.yearSelector, this.context).val(0).change();
} catch (e) {
CLIENT.Utilities.postWarnMessage('', 'DatePicker.js clearDate()', e);
}
};


this.setupControls = function () {
try {
$(this.datePickerSelector, this.context).change(this.hdlChange);

$(this.datePickerSelector, this.context).datepicker({
showOn: 'button',
buttonImage: '/new_cms/images/calendar.png',
buttonImageOnly: true,
onSelect: this.hdlDatePickerSelect
});

//give the date control a reference to the 'this' DatePicker object,
//so that event handlers can access the DatePicker object
$(this.datePickerSelector, this.context)[0].theThis = this;
} catch (e) {
CLIENT.Utilities.postWarnMessage('', 'DatePicker.js setupControls()', e);
}
};

//event handlers for which 'this' is the date control, not the DatePicker object
this.hdlChange = function () {
try {
//retrieve the object reference from the date control
var myThis = this.theThis;

var dateText = $(myThis.datePickerSelector, myThis.context).val();
if ($.trim(dateText).length > 0) {
var date = CLIENT.Utilities.parseDateString(dateText, $(myThis.datePickerSelector, myThis.context));
if (date) {
myThis.setDate(date);
} else {
$(myThis.datePickerSelector, myThis.context).val('');
myThis.clearDate();
}
} else {
myThis.clearDate();
}
} catch (e) {
CLIENT.Utilities.postWarnMessage('', 'DatePicker.js hdlChange()', e);
}
};

this.hdlDatePickerSelect = function (dateText, inst) {
try {
//retrieve the object reference from the date control
var myThis = this.theThis;

CLIENT.Utilities.clearValidationMessages($(myThis.datePickerSelector, myThis.context).parent());
if ($.trim(dateText).length > 0) {
var date = new Date(dateText);
myThis.setDate(date);
} else {
myThis.clearDate();
}
} catch (e) {
CLIENT.Utilities.postWarnMessage('', 'DatePicker.js hdlDatePickerSelect()', e);
}
};
};



Example HTML:



<div id="divGeneralJournal">
* * *
<label for="invoiceDateGeneralJournal">Invoice date</label>
<input type="text" id="invoiceDateGeneralJournal" value="" class="datefield" />

<input type="hidden" id="invoiceMonth" />
<input type="hidden" id="invoiceDay" />
<input type="hidden" id="invoiceYear" />
* * *
</div>



Initialization script would go something like this:



var invoiceDatePicker = new CLIENT.Utilities.DatePicker('#divGeneralJournal', 'GeneralJournal', 'invoice');
invoiceDatePicker.setupControls();

21 May 2010

Alpha bravo charlie

Every software development effort more complex than an accountant bashing away with Excel macros divides itself into phases. Practitioners sometimes assign simple sequential numbers to the phases of a project, but number-based designators often don't work out because phases overlap, get rescheduled, subdivided, and cancelled—who wants to explain to management that Phase 3.7 will be completed after Phase 6.2? And numbers don't have much sizzle. While they do have the advantage of being arbitrary, they still imply a precedence.

Temporal designators ("the fall '09 release") are even worse, because we all know that sometimes the fall release is completed the following summer.

And so we use code names, and the more arbitrary but transparent the better. They function in much the same way that journalists use slugs to identify stories. A slug doesn't tell you what's in a news story—the headline and teaser do that. It's just enough of an identifier so that you know which story you're talking about in an page space budget meeting. Monday's story on a key Senate floor action might be slugged HEALTHCAREVOTE. In fact, you need the slug in order to conceptually manipulate the story even before you know the story's outcome. Not unlike many software projects I've known.

Choosing the pattern for a group of code names is an important decision, and one best left not to the group, but rather to one person. Group-chosen patterns are rather bland and uninteresting. At a previous job, the whole company voted on the pattern and we ended up with "Caribbean resort islands." And so I worked on Aruba, and Barbados, and Coba, etc. Blah. Or way too pretentious: names from Greek mythology was another popular pattern there.

Much better is the approach that my current client uses. Each January, the code names start following a new pattern at the beginning of the alphabet, but the pattern is left a mystery known only to the project management office, which doles out the names a few letters at a time. The first team member who susses out the pattern—and mind you, this is an honor system thing, no search engines allowed—gets to choose the pattern for the next year.

And so phases for this year were named Abby, Biff, Claribelle (a tantalizingly distinctive spelling), Domby, and so on. One of us, Kate, eventually cracked the code at Kami. I wonder what Kate will give us next year?

01 May 2010

Tik tok

D.C. area residents interested in the Antikythera Mechanism have an opportunity to learn more at a lecture to be given by John Seiradakis (professor of astronomy, Aristotle University of Thessaloniki) and Tom Malzbender (senior research scientist, Hewlett-Packard Laboratories) later this month.