June 23, 2009


Filed under: Uncategorized — frameworker @ 4:50 am

I realize this document is pretty dry, but I needed to document this implementation to facilitate discussion with othere in the quest to improve it. Without going into why I took the approach I did, I will say that I did become very proficient in using strings with Objective C 🙂



Expressions are written in infix notation, just as you’d expect. They consist of OPERATORS, OPERANDS, SEPARATORS and FUNCTION NAMES.


== <= or == or => != or && || !


+ – * % (modulus) ^ (exponentiation)

B. OPERANDS may be cell references or numbers. Numbers are evaluated as double-precision floating point.

C. SEPARATORS include ( ) , ;

The “=” character is prepended to all expressions, just like in VisiCalc.

D. All other tokens, those which are not OPERATORS, OPERANDS or SEPARATORS, are FUNCTION NAMES.

FUNCTION NAMES that end with “TABLE” are a special case. They perform Table Lookups for forms that use Tax Tables.


Operands, within formulae, may be cell references or numbers. Numbers are evaluated as double-precision floating point.


Boolean Formulae, expressions that resolve to YES (1) or NO (0), are used in the scriptIf component of Conditional Expressions. They aren’t used elsewhere at this time, but they could be. Any positive number could be interpreted as YES, but we currently require “1”.


Functions are snippets of code that get dispatched interpretively.

Function arguments may be formulae or can, themselves, be functions.

Quotes are used to transmit function (and table lookup) arguments as literals.

*Describe how a function gets added to PDQForms and the function dispatch mechanism.*
*Show the recursive function parsing routine.*


Table Lookups are used to find income tax, for example, for Federal filers whose taxable income is less than $100,000.

See the blog post on TABLE LOOKUPS IN PDQFORMS for a more detailed description of how they’re implemented.


Conditional Expressions are of the form =IF(scriptIf;scriptThen;scriptElse)

(“IF” is a reserved word)

ScriptIf, a Boolean Formula, resolves to a value of zero or one. If scriptIf resolves to 0, scriptThen is executed, otherwise scriptElse is executed. ScriptThen and scriptElse can be Table Lookups, Functions or Formulae.

Conditional Expressions may not be “nested.”


Expressions may not contain functions. For now, if an expression needs an embedded function, an invisible widget, that calls the function, can be referenced from the expression.


April 30, 2009

[RECOMMEND] Jordan Langille, Iconographer

Filed under: Uncategorized — frameworker @ 7:53 pm

Jordan is an Artist and Iconographer at OneToad Design

He designed the icons for PDQForms 🙂

I found Jordan through CIMGF; thanks guys!

Jordan responded to my initial query, worked with me and delivered my icons in a very reasonable amount of time!

He communicates well, is easy to work with, and does EXCELLENT WORK!

And he’s very concerned with his customers’ satisfaction!

Thank you, Jordan!!

Daring Furball

Filed under: Uncategorized — frameworker @ 5:20 pm


Buster was taking a break from writing his application for the 2009 Apple Design Awards – he’d been working extensively with Mouse Events, of course.

Perhaps he was drawn to the laundry basket by my – freshly minted and washed – Daring Fireball t-shirt 🙂

April 16, 2009

Windows considered harmful :-)

Filed under: Uncategorized — frameworker @ 8:49 pm

“you guys are outta yer minds”

April 10, 2009

Announcing PDQForms

Filed under: Uncategorized — frameworker @ 6:02 am


PDQForms is a Mac OS X application that adds spreadsheet logic to regular tax forms* so you can file your Federal and State** tax returns quickly, avoiding tedious calculation, and with accurate results. PDQForms is for people who do their own taxes, want to maintain the privacy of their financial information, and want high-quality, low-cost tax software.

* These forms have been “fixed up” to contain embedded logic.
** The 2009 edition supports only CA and NY State returns.


“Things should be as simple as possible, but no simpler.”
– Albert Einstein

PDQForms seamlessly integrates intelligence into familiar, paper-based forms, eliminating tedious calculation while ensuring accurate results. This simplicity of familiarity is PDQForms’ “platform innovation.”


PDQForms implements smart layout to always center the active field within its focus ring. Almost all calculations are performed automatically, including tax calculations, which are done using the appropriate tax table or formula.

Compare this to the haphazard experience of filling out tax forms using Acrobat Reader or Preview, with their erratic field positioning, dollars and cents fields that are split in two, and no built-in support for calculations.


PDQForms has a small memory footprint to launch quickly. It’s quite responsive, with no noticeable hesitation when editing or tabbing between fields. Tested with Leopard Instruments and the LLVM/Clang static analyzer, PDQForms is also extremely stable.


PDQForms is fully Unicode-compliant, ensuring ease of localization.


The PDQForms website is here.

December 17, 2008

One More Thing…

Filed under: Uncategorized — frameworker @ 3:10 am

Amit Sing has posted a great writeup of his, and Ted Bonkenburg’s, most excellent “MacFUSE State of the Union Talk (2008).”

If you weren’t planning on watching the video, due to its hour and twenty minute length, fast forward to 01:12:17 and start there. You’re in for a real treat! While it would be better if viewed in its entirety, after watching the end you just might want to rewind and take in the whole thing.

As I said to Deric Horn, who was there from Apple, afterwards: “My mind is completely blown.”

December 9, 2008

Amit and Ted’s Excellent Demo!

Filed under: Uncategorized — frameworker @ 6:22 am

This afternoon, I went to “Amit Singh’s MacFUSE State of the Union.” It was awesome, both in terms of content and presentation.

Of great significance to developers like me, Ted Bonkenburg has developed an Objective C interface for MacFuse 2.0 complete with project templates.

UPDATE: The MacFUSE State of the Union video is available here 🙂

November 15, 2008

Tabbing in PDF Annotation Editor

Filed under: Uncategorized — frameworker @ 8:09 pm

Written by John Calhoun, the PDF Annotation Editor is a sample application that uses PDF Kit to examine, edit, and create PDF annotations. 

It lets you tab in Test mode but not in Edit mode.

I needed to tab in Edit mode, but was headed in the wrong direction when John Calhoun graciously provided this recipé:

“Grab keyDown’s in your PDFView subclass and keep track of the current annotation with “focus”.  Manually advance the focus by going round-robin through the annotations on the page.”

Here is its implementation:

// Add a case to [PDFViewEdit keyDown] to detect the Tab key
// and call "advanceFocus" when it is hit.
- (void) keyDown: (NSEvent *) theEvent
    unichar oneChar;

    // Skip out if not in 'edit mode'.
    if (_editMode == NO)
        [super keyDown: theEvent];

    // Get the character from the keyDown event.
    oneChar = [[theEvent charactersIgnoringModifiers] characterAtIndex: 0];

    // Delete or Tab ?
    if ((oneChar == NSDeleteCharacter) || (oneChar == NSDeleteFunctionKey))
        [self delete: self];
    else if (oneChar == NSTabCharacter)
        [self advanceFocus];
        [super keyDown: theEvent];

Add two methods to PDFViewEdit.m
and their method declarations to PDFViewEdit.h.

// Tab key was hit; move focus to the next widget.
- (void) advanceFocus
    if (_activeAnnotation != NULL)
        PDFPage * currentPage = [_activeAnnotation page];

        // Walk array of annotations.
        NSArray *annotations = [currentPage annotations];
        int annotCount = [annotations count];

        int activeIndex = [annotations indexOfObject: _activeAnnotation];

        int newActiveIndex = [self nextAnnotIndex: activeIndex withinCount: annotCount];

        PDFAnnotation * newActiveAnnotation = [annotations objectAtIndex: newActiveIndex];

        [self selectAnnotation: newActiveAnnotation];

// return the index of the next annot, wrapping around on the current page.
– (int) nextAnnotIndex: (int) activeIndex withinCount: (int) annotCountForPage
    int nextIndex = -1;

if (activeIndex +1 < annotCountForPage)     {         nextIndex = activeIndex + 1;     }     else     {         nextIndex = 0; // Wrap around on page.     }     return nextIndex; } [/sourcecode] Voilà, that's all there is to it!  Thanks John!

November 9, 2008

Plan B

Filed under: Uncategorized — frameworker @ 12:20 am

Plan B: A backup plan for unforseen contingencies.

Plan B is an interactive PDF forms editor that lets you edit, save and re-edit PDF forms. It requires OS X 10.5.

UPDATE: Preview now lets you save and re-edit PDF forms! So, for all practical purposes, Plan B is defunct (along with Buffalo Bill).

To install Plan B in your Applications folder, first download Plan B, then double-click its dmg file. Next, drag the Plan B icon onto the Applications folder alias in the Plan B.dmg window.

Your edited forms data will only be visible in Plan B. To make the edited form viewable (but not editable) by another PDF viewer like Preview, flatten the file by doing a “Save as PDF…” in Plan B’s “Print…” dialog.

There is no charge to use Plan B, although its use is governed by the EULA you accepted by downloading it.

Your feedback will be appreciated!

UPDATE: The original upload, version ß2, only worked on Intel hardware; I’ve uploaded version ß3 which is a Universal Binary.

August 1, 2008

Gel Tracker

Filed under: Uncategorized — frameworker @ 3:23 am

Gel Tracker was a program used to “track and extract” DNA data from “sequenced gels.” It was my full-time project from December 1996 until June 1998. I wrote it in C++ using MacApp.

Gel Tracker drew lines, interactively, down the center of each lane on a gel to identify the data slices to be extracted for sequencing. It also used an auto-tracking algorithm, I wrote, that radically improved tracking accuracy and efficiency. I also implemented a panel display to visualize chromatograms for tracking validation.

Milestones Leading to Automated DNA Sequencing

This is not a comprehensive history of the “Genomic universe,” just a rough timeline to show where Gel Tracking fit into the scheme of things in DNA sequencing.

1953 – The molecular structure of the DNA molecule is discovered. (Watson & Crick)
1977 – DNA sequencing by electrophoresis (Frederick Sanger)
1983 – PCR enables rapid amplification of DNA (Kary Mullis)
1984 – Four color dye method of sequencing developed (Tim Hunkapillar)

Automated DNA Sequencers

1986 – ABI 370A
1990 – ABI 373A
1995 – ABI 377
1996 – ABI 377 96-lanes

Tracking a Gel

The early sequencers used slab gels. The “sequenced gel” looked like a series of multi-colored ribbons running down a glass plate plate. It was necessary to “track the gel,” that is, to define the locus of each lane, so the underlying data could be extracted, the next step in the bioinformatic data stream.

When you look at a Gel Image, you see a four color image: Red, Green, Yellow and Blue. While each point in a gel image has four intensity values, one for each dye, only the most intense color is displayed at each pixel to enhance the visualization of DNA sequence data.

Gel Tracker window containing a tracked 96-lane gel:


You can see comb makers to the left and lane markers above the gel. The lanes are depicted as vertical white lines with selection handles at points where the lanes and combs intersect. (The handles turn red if they are “selected.”)

The Interface

As “Moore’s Law” played out in sequencing, lane geometry became increasingly tight. With the advent of the 96 lane sequencer, lane separation was no longer always obvious. So it became necessary to augment user tracking with algorithms to largely automate the tracking process.

The 96-lane gel has a gap between two sets of 48 lanes. If a gel was good*, and a lot of them were, you could track the outside lanes of each 48 lane group. Then interpolate each of the two interior lane sets and auto-track them. Sometimes, auto-tracking a second time would improve the results slightly, where the auto tracking algorithm had been a bit “conservative” for the given data.

Selection was just a matter of dragging a selection rectangle over the lane markers you wanted to include. You could, additionally, Command-click to invert the selection state of individual lanes or Shift-click to affect multiple lanes.

* High flourescence saturation, reactions completed for practically all lanes (i.e. no “dropouts”), uniform lane spacing.

Visualizing DNA Data for Extraction

The key to optimizing gel tracking was to auto-track good gels but to have an interface that visualized the gel for manual tracking as a fall-back for bad gels. Adding the chromatogram panel accomplished that by allowing users to interactively observe a slice of the gel as it was being tracked. By noticing the amplitude of the chromatogram and watching its “Chrom value,” the user could find the optimal path for any lane.

The chromatogram panel allows you to visualize a slice of the gel when a single lane is selected. It’s implemented with a synchronous scroller so that it always matches the selected lane as the gel is zoomed and scrolled.

In 1987, as a Christmas present to his wife who was a geologist, Larry Tesler who had invented MacApp, added Synchronous Scrolling to MacApp for visualizing scientific information. Here, ten years later, I was also using it for just that, in biochemestry.

Visualizing chromatogram data conferred many benefits:

• Made it easier to Track difficult parts of a gel.
• Provided interactive feedback to shorten the “learning-curve” for new users.
• Helped users develop confidence in auto-tracking and understand other Gel Tracker features.
• Was essential for testing Gel Tracker, especially in conjunction with the “Chrom value” field.

Tracking detail with chromatogram:


Gel Tracker Architecture

Gel Tracker was implented with MacApp which provided general mechanisms for user interaction: selection, dragging, tracking feedback and one level of undo/redo. I loved MacApp!

MacApp’s View architecture perfectly supported Gel Tracking and the addition of USynchScroller, used to visualize “data slices,” was “icing on the cake”!

The adjustable lane map overlaid the gel view. When the lanes were retracked either manually or automatically, the affected extent of the gel view was invalidated and redrawn, using an offscreen bitmap, prior to updating the lane map.

Scrolling and Zooming

Scrolling and zooming performance was quite good, minimizing flicker, because of the offscreen bitmap. But to further reduce flicker, I kept a grey scroller underneath the gel. Only visible during invalidation, it made the perceived flicker practically vanish!

In the figure, “Tracking detail with chromatogram,” you can see the zoom controls between the ACGT buttons and the Sample Name text field. The gel is shown fully zoomed-in, so the horizontal and vertical magnification controls are dimmed.

When zooming, lane map positioning is conserved by numerically scaling the lane map. It’s also necessary to compensate for the fact that the zoomed image representation may be “downsampled,” a slight wrinkle.

Downsampling is a technique to visualize a reduced gel image. Rather than taking every nth vertical pixel, swaths of contiguous pixels are taken – still in proportion to the zoom factor – to maintain the characteristic appearance of DNA data.


Auto-tracking was performed, first, by shifting each tracking segment left or right, then by adjusting its slope and, finally, by “annealing” the endpoints of adjoining segments to maximize the lane’s image value.

The lane’s image value is the sum of intensity values for each pixel under each of its segments.


Of importance, the first two stages of auto-tracking are constrained by “edge detection” when the number of color changes between an original and alternate segment position exceeds a preset value.

When this occurs, it is assumed that a lane boundary has been reached and auto-tracking is halted for that stage.

In honor of Tim Hunkapillar, who besides being a world-class biochemist, was a big fan of The Rocky Horror Picture Show, the first phase of auto-tracking was eponymously named “The Time-Warp,” for the song from that movie containing the lyric: “just a jump to the left, then a jump to the right.”

An Anecdote

Early in the project, I encountered a really weird toolbox “bug” that drove me nuts. In my “jihad” to defeat it, I was fortunate to find one of the last existing copies of Programming QuickDraw (which had been published six years earlier, in 1991) in Stacey’s Bookstore in Palo Alto. When I still couldn’t figure out how to solve the problem, I called the author, David Surovell, who graciously spoke with me about it! In the end, the solution involved “QuickDraw Voodoo.” But David’s assistance in ruling everything else out, helped me keep my sanity and find the eventual solution!

« Newer PostsOlder Posts »

Create a free website or blog at