Archive for the ‘Andre Masella’ tag
Parsing a Newick Tree with recursive descent
>>> Attached: ( parse_newick.js – implementation in JS | index.html – example use ) <<<
Update: Fixed the pseudocode — the previous version was too wordy, this version is comfortably more algebraic.
This method of parsing works for any language that allows recursive functions — basically any of the curly bracket languages (C#, C, Java) and the fast-development languages (Ruby, JavaScript, Python) can do this. This particular example will include JavaScript code which you can take and do whatever you want with — recursive descent parsing is a well-known and solved problem, so it’s no skin off my back. Before we begin, I should probably explain what a tree in Newick format is.
What exactly is the Newick format?
Remember back in second year CS when your data structures / abstract data types / algorithms instructor said you can represent any tree as a traversal? Well, if not — don’t fret, it’s not hard to get the hang of.
A traversal is a finite, deterministic representation of a tree which can be thought of as a road map of how to visit each node of the tree exactly once. The phylogeny / bioinformatics people will know each of these nodes as either taxa / sequences (the leaves) or profiles (the internal nodes — i.e. not the leaves). A tree in Newick format is exactly that — a traversal. More specifically, it is a depth-first post-order traversal. When traversing a tree, we have a few options about how we want to visit the nodes — depth-first post-order means we want to start at the left-most, deepest leaf, and recursively visit all of the nodes before we end at the root.
A tree expressed in Newick format describes a tree as an observer has seen it having visited each node in a depth-first post-order traversal.
A node in the Newick format can be…
- A leaf in the form: “<name>:<branch_length>”
- e.g. “lcl|86165:-0“
- e.g. “gi|15072471:0.00759886“
- e.g. “gi|221105210:0.00759886“
- Or a node in the form “(<node>,<node>):<branch_length>”
- This is where it gets tricky and recursive — the “node” item above can be another node, or a leaf — when a node is composed of at least another node, we call that a recursive case; when a node is composed of only leaves, we call that a base case. We make this clearer in the next section.
- Or a node in the form “(<node>,<node>);”
- The semi-colon at the end means that we have finished describing the tree. There is no branch length as the root of the tree is not connected to a parent.
Understanding recursion in a Newick Tree
Base case e.g.: The below node is composed of two leaves.
“(lcl|86165:-0,gi|87118305:-0):0.321158”
Recursive case e.g.: The below node is composed of a leaf on the left, and another node on the right; this right-node is composed of two leaves.
“(gi|71388322:0.0345038,(gi|221107809:0.00952396,gi|221101741:0.00952396):0.0249798):0.0111081“
If the names look a bit funny, that’s because these are sequences pulled out of a blastp search.
The Newick tree itself may have any number of nodes, the base case being a single node. The only restriction is that any node either is a leaf (has zero children) or must have two children (never a single child). These two children again are allowed to be either leaves or other nodes.
We would visualize the above Recursive case e.g. as follows.:

Where the numbers beside the edges are edge length and the names of the named taxa are indicated inside the circles (leaves). The unnamed internal nodes are the profiles that have been calculated with alignments. You’ll notice that there’s a branch length leading out of the root of this subtree into the rest of the tree (not shown). If this was a complete tree on its own, the root would have no branch length there and no arrow coming out of it.
Finally, Parsing!
Now that we have reviewed the depth-first post-order traversal, the Newick format and how to interpret it; we can move onto parsing these things. In parsing, we hope to create an in-memory structure that represents the tree. The parser I discuss assumes that the Newick format string already has had all newlines stripped, as it uses regular expressions. If your trees aren’t stored that way, just make sure that newlines are stripped before feeding it into my function. The in-memory object that’s created will have the following fields as a minimum.
- node_type $left – the left child of a node
- node_type $right – the right child of a node
- string_type $name – the name of a node (if it is a leaf)
- float_type $branch_length – the length of the branch coming out of the top of a given node
I also use the following two fields to keep track of a few house keeping items and to make life pleasant for future tasks with this in-memory structure.
- node_type $parent – the parent of a node
- integer_type $serial – the order in which this node occurs when parsed
Note that in future, a depth-first post-order traversal will yield the nodes in the exact order that they were read — so in reality “this.serial” isn’t really needed, but it’s nice to have for future functions you might write as a shorthand. Have you understood why these nodes would occur in the same order?
Each language has its own quirks. Python and JavaScript have the advantage that you can define a class and define its properties (fields) on the fly — meaning there’s less code to download and to write, which is particularly good for blogs
Here’s pseudo-code for the recursive descent parsing function “tree_builder(<newick_string>)” — I don’t indicate where to strip away newlines because I assume they’re gone. I also don’t indicate where to strip away whitespace (I did previously, but that took up like half the pseudocode). So if there’s a place where you suspect whitespace can occur, strip it away and increment the cursor by the length of that whitespace.
Note: We are assuming that there are no newlines in the file — that is, the entire newick traversal is one string on a single long unbroken line.
// Note:
// Call tree_builder() with a "new" operator in JavaScript
// to allow it to use the 'this' keyword.
// In other languages,
// you may need to explicitly create a new object instead of using 'this'.
var count = 0; // can be either a global variable or a reference
// keeps track of how many nodes we've seen
var cursor = 0; // also either a global or a reference
// keeps track of where in the string we are
function tree_builder(newick_string) {
// Look for things relating to the left child of this node //
if $newick_string [ $cursor ] == '(' {
$cursor ++; // move cursor to position after '('.
if newick_string [ $cursor ] == '(' {
// Then the $left node is an internal node: requires recursion //
$this.left = new tree_builder(newick_string); // RECURSIVE CALL.
$this.left.parent = $this;
}
// try to find a valid $name next at the current cursor position //
if $name = $newick_string [ $cursor ] . regex match ("^[0-9A-Za-z_|]+") {
// Then the $left node is a leaf node: parse the leaf data //
$this.left = new Object;
$this.left.name = $name;
$this.left.serial = $count;
$count ++;
$this.left.parent = $this;
$cursor += length of $name;
// move cursor to position after matched name.
}
// notice: if no $name found, just skip to finding branch length.
}
if $newick_string [ $cursor ] == ':' {
// Expect left branch length after descending into the left child //
$cursor ++; // move cursor to position after the colon.
// look for the string representation of a floating point value "FPV"...
$branch_length_string =
$newick_string [ $cursor ] . regex match ("^[0-9.+eE-]+");
$this.$left.$score = $branch_length_string as a FPV;
$cursor += length of the string $branch_length_string;
// move cursor after FPV.
}
// Look for things related to the right node //
if $newick_string [ $cursor ] == ',' {
$cursor ++; // move cursor after the comma
if newick_string [ $cursor ] == '(' {
// Then the $right node is an internal node: requires recursion //
$this.right = new tree_builder($newick_string); // RECURSIVE CALL.
$this.right.parent = $this;
}
// try to find a valid $name next at the current cursor position //
if $name = $newick_string [ $cursor ] . regex match ("^[0-9A-Za-z_|]+") {
// Then the $right node is a leaf node: parse the leaf data //
$this.right = new Object;
$this.right.name = $name;
$this.right.serial = $count;
$serial ++;
$this.right.parent = $this;
$cursor += $length of $name;
}
// again, accept if no $name found and move onto branch length.
}
// Now looking for the branch length ... //
if $newick_string at $cursor == ':' {
// Expect right branch length after descending into right child //
$cursor ++; // moving past the colon.
$branch_length_string =
$newick_string [ $cursor ] . regex match ("^[0-9.+eE-]+");
$this.right.score = $branch_length_string as a FPV;
$cursor += length of the string $branch_length_string;
}
if $newick_string at $cursor == ')' {
$cursor ++; // move past ')'.
}
// Expect the branch length of $this node after analyzing both children //
if $newick_string at $cursor == ':') {
$cursor ++;
$branch_length_string =
$newick_string [ $cursor ] . regex match ("^[0-9.+eE-]+");
$this.score = $branch_length_string as a FPV;
$cursor += length of the string $branch_length_string;
}
if $newick_string at $cursor == ';') {
// This case only executes for the root node-- //
// --the very last node to finish parsing //
$cursor ++; // to account for the semicolon (optional, consistency)
$this.serial = $count; // no need to increment $count here
}
// Return to complete a recursive instance (internal) or base case (leaf) //
return this; // not needed if "new" operator was used all along
}
The implementation that’s included in the attached JavaScript does two things differently than the above. First, I don’t force the user to break encapsulation by declaring globals. Instead, I use an object called “ref” which has two fields, “ref.count” and “ref.cursor”. The name “ref” is chosen to remind us that its fields are passed by reference. This is possible because the object “ref” itself is passed by reference (I could have called it anything, but I chose a name that suited its purpose). Imagine trying to pass “count” and “cursor” in this recursive function without an enclosing object — what would happen instead is that the value wouldn’t be updated, instead the integer values would be copied and modified locally in the span of single function instances. The “ref” object is passed as an argument to the “_tree_builder(<ref>, <newick_string>)” function internally where it is instantiated if “null” is passed in the place of “ref”. The calling user doesn’t even need to know about it, as it’s all wrapped together in a pretty package and the user just calls “tree_builder(<newick_string>)” as before — without the need for globals. The enclosing function even does the work of instantiating the root node with the “new” keyword so that the end user doesn’t even need to (and shouldn’t!) say “new”.
Finally, there is a traversal function, and an expose function. The traversal function returns the node objects in an array following in the natural depth-first post-order described previously. The expose function is a debugging function which writes the output using “thoughts_write(<message>)” which wraps “document.write(<message>)”. You can change “thoughts_write(<message>)” to print output elsewhere using “document.getElementById(<some_identity>).innerHTML += (<message>)” where “some_identity” is the “id” of some element in your HTML. Without going into detail, the traversal function also uses an internal “ref” object which refers to the array as it is filled.
Some other things you can try…
The JavaScript recursive descent parser is actually a simplified version of something that I threw together earlier. The major difference is that I tag leaf nodes with fasta protein sequences by passing a reference to an associative array (or hash) as an argument to “tree_builder(<newick_string>, <fasta_hash>)”. Remember, in JavaScript, an associative array is an instance of an Object, not an instance of an Array. Using non-integer field names in an Array is actually not well defined but kind of sort of works semi-consistently between browsers (i.e. don’t try!), but that’s a story for another day. Whenever the name of a leaf is parsed, I would look it up in the hash and put it in a field either “this.left.fasta” or “this.right.fasta” thereby conferring to the leaf nodes of the in-memory structure the appropriate fasta protein sequence.
Lessons Learned
In putting this thing together, I managed to relearn JS, recursive descent parsing and making JS pass things by reference up and down a recursive stack of function calls. Andre Masella helpfully reminded me that I didn’t need to use any kind of BNF or LALR(1) parser — just an easy single-function parser would do. This is actually a port of a C# parser which does the same thing that I wrote in an earlier step for phylogenetic analysis — the difference being that C# offers a “ref” keyword that allows one to specify arguments in a function’s parameter list as emulated references (functionally equivalent to using C’s asterisk and ampersand convention though not operationally equivalent).
Happy parsing! The code presented should be easy enough to understand for you to port it into the language of your choice for whatever purposes you design.
Apache Optimized Finally! (Firebug, YSlow)
I didn’t realize I hadn’t added the mod_expires.c and mod_deflate.c items to my httpd.conf file in Apache yet– Andre clued me in!
Andre noticed my blog was taking a while to load, even when the browser cache should have significantly dented the page weight. He used Firebug and Yahoo’s YSlow to make a diagnosis and told me to do the same– this page ended up taking a whopping 17 seconds to load which is … very … sad. After I added these lines to my httpd.conf file, things were looking better (roughly 1.5 seconds — not perfect, but it’s far better).
The mod_expires.c chunk specifies that files displayed on a webpage ought to live in the browser cache. The caching information is sent as part of the file header by Apache to the client browser. Without this, files were apparently expiring instantly meaning that each refresh required downloading every single file again including including the images comprising this theme’s background.
The mod_deflate.c chunk specifies that file data should be gzipped before transmitting– this is again handled by Apache. The trade off between compressing a few text files (even dynamically generated ones) versus sending uncompressed text is more than fair.
<IfModule mod_expires.c>
FileETag MTime Size
ExpiresActive On
ExpiresByType image/gif "access plus 2 months"
ExpiresByType image/png "access plus 2 months"
ExpiresByType image/jpeg "access plus 2 months"
ExpiresByType text/css "access plus 2 months"
ExpiresByType application/js "access plus 2 months"
ExpiresByType application/javascript "access plus 2 months"
ExpiresByType application/x-javascript "access plus 2 months"
</IfModule>
<IfModule mod_deflate.c>
# these are known to be safe with MSIE 6
AddOutputFilterByType DEFLATE text/html text/plain text/xml
# everything else may cause problems with MSIE 6
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/ecmascript
AddOutputFilterByType DEFLATE application/rss+xml
</IfModule>
I’ve also removed the custom truetype font files specified in the CSS… they aren’t handled correctly for whatever reason– even after I added ‘font/ttf’ entries to the mod_expires.c chunk above. Finally, I tried completely removing background images from the site and restoring them again– it doesn’t make things any faster after images have been cached (correctly, finally).
I am very happy.
fsMSA Algorithm… Monkeys in a β-Barrel…
I’ve finally finished documenting my foil sensitive protein sequence algorithm… This is part of Monkeys in a β-Barrel — a work in progress, this time continuing more on Andrew’s half of the problem rather than Aron’s.
I’ve decided on using the word “foil” to mean “internal repeat” since it’s easier to say and less awkward in written sentences. Andre suggested it after “trefoil” and “cinquefoil”, the plant.
Thumbnails below (if you are curious about the full slide show, contact me
).
fridgelib — Andre’s C Library
Brief: Fridge Library (fridgelib) is a light weight C library that’s basically what each C programmer eventually comes away with. Fridgelib contains a queue, stack and trie data type implementation– these implementations are cleaner than mine, hence I have devoured them into my code where necessary.
There is however one item that Andre’s told me I can add to fridgelib if I can ever tidy it up, and that’s my evil linked-array. It’s basically a doubly linked list whose elements are arrays of fixed size; the traversal is cut down by a multiple of that array size while indexing thereafter is still constant time given the modulus of the index. My evil implementation is a double-headed stack/queue/array which supported python-like negative-value indexing, slicing and iteration… actually, that’s when I decided it had grown too grotesque and left it to sit in my repository…
I’ll probably return to it later, to remove slicing and to more cleanly define the semantics of iteration.
Hmm– the only things that are really missing from fridgelib are the hashtable and either a nice red-black tree or a treap…
Yo! Holy crap you have a blog. Interesting concept of a linked array. Do the allocations increase exponentially? You would have an interesting problem trying to keep constant time because even if your allocations increase exponentially, if you have a large number, you would have to traverse the small nodes first.
No, the allocations increase at a constant size
The modulus short cut can only work that way– this pseudocode should clear it up… I haven’t checked for off-by-one logical errors– this’ll give you the sense of what I’m doing though.
Pseudocode:
function get linkedArray this, int index:
int which_page = index / length of one internal array
int which_index_in_page = index % length of one internal array
internalArray this_page = this -> start
for int i = 0; i < which_page; i++
this_page = this_page ->> next
return this_page -> array[ which_index_in_page ]
struct linkedArray:
int length of one internal array
internalArray start
struct internalArray:
generic array
internalArray next
Note that I haven’t added anything in the above to convert out of Python-style negative-indices– I also had an optimization that would traverse the list of arrays from the last internal array instead of the first internal array if the selected index is actually on a ‘page’ that’s past the midpoint of the list.
Edit: Getting pseudocode in html to work well in WordPress comments is a pain…
Hmm, if you double the number and start the array size at 1, the capacity:
sum of 1->numPages 2**maxIndex
You could either do a O(lg(maxIndex)) (using bit shifting) access if you don’t store where all the pages start, or a O(1) access if you do. It’s an extra 4 bytes per page plus the occasional expansion of the index which should happen seldomly. That way inserts are no longer a max O(numberInserted/number per array) but O(lg(numberInserted)).
Heavier on the memory but saves big time on write time. I like this idea though, never heard of a linked array. Arbitrary inserts aren’t so bad because you can just expand one array rather than all of them, that’s so smart!
I suppose though, if you knew that the inserts were constant, then your data structure would be better. It really does depend on application.
The Return of Phi C31
I’ve been so out of the loop with iGEM over the last month. I’ll need to figure out how to get back into the swing of things, probably starting with the post mortem meeting on Tuesday. Generally, since no new maths could be put on the table that actually encompassed the problem well– the brute force approach was kicked into high gear with a few more filters to increase the probability of success.
Call these “System Filters” since they aren’t really based on biologically significant concepts, really just sanity checks that are conceptually consistent with the project (i.e. we’d run out of hard disk space otherwise…). Significantly, Matthew implemented “Blank Stare”, which destroys reactants that exceed a given length (thus preventing them from hogging the CPU looking for less parsimonious solutions). Less significant were Andre’s “Lone Gunman” which deletes arbitrary chromosomes with stochastic efficiency and my “Tag” which prevents chromosomes from cross reacting.
(On second thought, “Tag” IS a “Biological Filter” not a “System Filter” because it removes redundancy by implementing the rule that we only admit bacteria that have exactly one chromosome.)
I should mention that “significance” above isn’t about the triviality of the code, it’s about the amount of anticipated efficiency boon we’d gain from an item’s deployment.
Tomorrow’s post mortem will continue the work I’ve started on our iGEM 2009 Wiki Modelling page… We’ll decide what we want to mention, how close we got to our solution and figure out how to precisely characterize the problem space uncovered by our various attempts.
Additionally, we should probably discuss the relevance of John’s attN site cloning and tests to see if the operators show any sign of degeneracy, and which ones in particular.
Finally, I should mention that Brandon has been working on a C++ port of the whole application we wrote in Python to elucidate how much the virtual machine impacted the performance of our solver– the team is quite divided on this idea with a big half (myself included) thinking that the exponential growth due to the algorithm is the greater factor– Brandon may have some answers for us when it’s up and running.
DNA … Knots and Lambdas
A long time ago, one Andre lead a team of students in a journey of mathematical and computational modeling; at the very least, we have reached some useful insights from our tidy trip albeit at a distance from the solution.
Presented here is a very jumbled, very abridged account of the activities of the modeling team this summer and the eventual realization that brings us to now.
The Problem Revisited
So we have a sequence. Actually, two sequences. Actually, we have two loops. Two loops of DNA that will contain a specific sequence used for cassette exchange. The problem is the design of these two loops. We want to design them so that we can predictably exchange specific objects between them. We used an enzyme for recombination that is sensitive to specific sites to perform the exchanges.
The above paragraph is an abstract-abstract of the UW iGem Project.
The Top Down Approach
What I eventually labeled in my mind as the top-down approach is called that in analogy to parsing. In parsing, we build a tree. We can do this conceptually from the bottom-up, or from the top-down. From the bottom-up, we know everything we need to know to build the tree… we know as much as we want to know, we even know if there exists not a tree for this particular string of tokens. From the top-down, we’d have to use some magical induction to chain tokens together by determining a structure that the tokens will find pleasing.
The magical induction of the top-down approach is none other than brute force. There is no magic, just an exponential explosion. The base of this power is the length of the string and the exponent of the power alludes to the complexity and depth of the grammar.
We don’t parse for the sequence problem– that is, we assume the grammar to be irrelevant, that a flat degenerate chain is a sufficient enough tree; we operate on sequences with our enzyme instead.
For our sequence problem, we pick three loops. We see if the first two loops add together with respect to the enzyme to make the third loop. By hand, one is tempted to use various heuristics of deductive logic but it became complicated and soon overflowed the allowed dozen or so objects a human brain may accommodate per instant. The machine was dragged in, and the three loops were shown to it using Python.
We presented three loops of one logical suite of tokens. It ran to completion and to no surprise, this was not our solution. We did this again for all three-loops where each loop is one logical suite. That ran to completion and again, no solution– again to be expected; not yet long enough to accommodate the anticipated length of the solution.
One logical block became two, became three… and at each step, the base of the exponent to our magical induction grew.
Four logical blocks… we halted the experiment; the machine would’ve taken a month to finish that block.
The exponential explosion was real, and our bid that the solution may be just short enough to fit therein was proven false.
The Bottom Up Approach
Months passed, various members went on various summer excursions… and many have returned now. We discuss many theoretical approaches. We resample the problem, sniffing for hints. Actually, it’s been Andre, Jordan and me … we haven’t discussed this with the remaining modeling team yet because of just how vague our new lines of intrigue are. I will revise my opinion if the thought that more individuals means faster solution finding crosses my mind again.
I’ve had a few conversations, one with my MSc advisor, Stefan; one with a friend Andrew Baker; and another with my undergraduate project advisor, Bettina. So far, no one’s seen this specific problem before or can allude to either an approach, technology or research that they’ve seen…
We reformalize the problem with the following constraints as follows.
- Must deal with circularity of DNA, hence by circularly shift invariant
- Must accommodate or encapsulate reverse complementation
Intrigue
Several lines of intrigue we visit now.
First, Knot Theory– provides a representation for knots as real-valued vectors; unique shapes however may produce degenerate vectors. Knots allow us to take our loop of DNA and place the putative recombinatory hotspots one on top of another. Missing from this item is precisely how to dope the vectors with our own sequence data.
Second, Lambda Math and Logical Programming provide a language and a method respectively to map vectors from left to right. The form of the abductive equations for this problem are yet to be discovered however. We’re thinking about this method because we suspect that the recombinase enzyme activity can be completely expressed as a mathematical construct on our doped knot vectors. We hope that this construct can be expressed with abductive statements.
Third, Recombinatory Calculus– actually, this item is in stark competition with Logical Programming as the functional crux of the model. Recombinatory Calculus which is fairly distant from Recombinatorics, mind– is a math that has shown all other math functions can be constructed by just two atoms. If it turns out that the final representation of a DNA loop looks more like arguments for these two atoms, then we may pursue this– but at present, it seems to be losing against Logical Programming– the allure of the two atoms subsides as we realized the complexity for even the addition function for integers.
Direction
Luckily… roughly a dozen papers have been recovered from various repositories that discuss knot math and how to hack it sufficiently to kindly represent DNA loops. We continue to read and discuss these papers until we feel it reasonable to raise it with the entire modeling group… that is, when the science is done and the engineering begins anew.
iGem Server is a Fussy Baby.
Brief: Going into the UWiGEM office today to meet with Andre at 10:30. Apparently, an attempt at installing a new hard drive wiped out the raid array. Andre’s already restored a lot of the system and files– obnoxiously large files notwithstanding, … and obnoxiously oddly-licensed software notwithstanding I’m thinking…
I, Moldy.
Andre showed me this cute little mold a while ago… I just stumbled on a video I shot of it along with some photos…



Apparently, rediscovering flasks full of unidentified growth where once only delicious media sat occurs every now and again in even the cleanest of labs. I’ll be sure to snap anything else that pops up.
Rather Hashing

Andre and Brandon
I’ve been away recently, so this task has apparently been uptaken by Jordan. The reverse-hashing integer-to-sequence function to be done for modeling was formalized a bit more in a meeting about two weeks ago, and I’ve yet to be briefed about what form it’s taken in yesterday’s meeting.
Update: Andre tells me that Jordan did in fact finish the sources, and everything ran overnight– however, the exponential explosion that we were afraid of ended up occurring; the present algorithm (part of which is described below) ran to the fourth iteration and well, would continue to run for a few weeks had it not been stopped… It looks like there’s ever more need for a working bottom-up approach…
Getting to absolute basics, this reverse hashing function converts positive integers to a sequence of arbitrary base strings– actually, I want to describe the general form of this function in case I need it in future. So if we know the size of the alphabet used for each character of a string, we can give each character a unique ordinal value. Two examples follow…

Brandon and Matthew
#Latin Alphabet (as used in English)
(A, 1), (B, 2), (C, 3), (D, 4) ... (Y, 25), (Z, 26), (null, 0)
#Nucleotides
(A, 1), (C, 2), (G, 3), (T, 4), (null, 0)
If we want to represent a string, we’d simply substitute the integer for the character.
#BADEGG
214577
#AGGCTT
133244

Bredth First Search Sphere
Bredth First Search Sphere [figure]… Andre used this chalkboard diagram to illustrate to Chong that this encoding conveniently increases in sequence length– we could consider this cardinality, or radius, or more importantly, the number of hops on a graph representation– when this problem is considered in lexicographic ordering, the implied algorithm is a bredth-first traversal.
We ran into a problem– this would at most represent one string. Brandon came up with a workaround, the notion of stealing characters from a sequence based on the modulus of its index! So, if we wanted to encode three strings, then every character at (index%3 = 0) belongs to string A. Strings B and C would then occupy (index%3 = 1) and (index%3 = 2) respectively.
Examples:
#Encode BADGE, FEED and AI together
#Pushes together as... BAA AEI DEx GDx Exx
#Where lowercase 'x' is null.
211159450740500
So that null symbols are inserted to preserve the correct location of each symbol.

3D 3Layer Cake
3D 3Layer Cake [figure]… An alternative approach to the encoding is to produce a triplet of integers instead of interweaving them; to farm out the sequences to be operated on, one would keep the entire domains of any two of the three sequences, while distributing the third; actually– this can still be done with the present encoding scheme, just farm out a fraction of the sequences based only on certain indexes of each sequence (the indexes satisfying the modulus math statements above). Abstractly, we can think of this as a three-dimensional cake where one dimension is distributed in layers– a three-serial-CPU-farm would consume a three-layered cake.
There’s one other thing I haven’t quite discussed, and that’s sequence sensitivity– Some sequences are masked so that the location of a certain integer implies a different entity depending on their position in their string– I’ll leave that for another post though.
I’ll have to discuss the bottom-up approach we’re going to try next– or not try at all since the modeling team is running very short on time; doing things by hand would either require inspiration, a marvel of human savant-like adduction or incredible luck… Jordan apparently demoed the algorithm by hand at the meeting I missed and showed the normal human mind can’t cope with the growth of the problem either…

Jordan playing a first person shooter...
Whoa, hold up: we ran the thing already? I have apparently fallen out of the loop.
I can’t say I’m really surprised that we ran into an exponential explosion. I had a feeling it would turn out this way when I tried to make a more useable UI and kept coming up with exploding test cases.
It looks like the easy solution’s pretty much killed off at this point. Time to break out the fun stuff?
Precisely — it’ll be a while though. In fact, keep your eyes open. If you come across some math that accommodates this problem well, figure out how we can use it.
oGEM: An iGEM Story
Thursday last week, the Waterloo iGem team had a online conference over Skype with the iGem teams of Toronto and Ottawa. Also present was Andrew Hessel– the seeder of Canadian iGEM teams… It was pretty extensive, so I’ll just discuss the parts that ended up being immediate goals for the Waterloo team.

oGEM Meeting Over Skype
The objective is to end up making an Ontario federation in synthetic biology under the iGEM scaffold a reality; we would eventually expand out of iGEM and cover synthetic biology across Canada, but — plan small, think big.
There must also be incentives for being part of such a federation– an obvious answer is a network of distributed services which are greater as oGEM than the sum of its parts.
Plan Small, Think Big
One of the first things we can experiment on is the idea of a social engineering application. This feature is being investigated by the Waterloo team– Arianne has created a mock-up using Elgg. The objective is to allow individuals across oGEM to know what expertise exists in the network, and to contact appropriate users for collaboration or help based on the interests or skills listed by each user.
Sigma is for Summation
Incentive services for oGEM are being tackled by our team. Andre wants to introduce a federated database of strains and cultures (codenamed BioMortar)– whereas iGEM offers clonable biobricks, the issue remains that cellular transformation is not deterministic. It may work some of the time, or most of the time– for some teams, certain bricks just aren’t successfully cloned. This federation would allow the cataloging of living frozen strains in freezers across oGEM and if users are willing, all synthetic open-source strains. Eventually, someone seeking a strain they’ve had issues with would message someone with a working copy as it were, and request it be shipped.
Caveats
We expect caveats to emerge– first of which is dedication. In our meeting, it is clear that working groups must emerge to take over tasks– working groups that are passionate about their own objectives. I suppose UWiGEM represents two working groups each operating on one of the above steps. Ottawa has volunteered to look at the legal caveats– how oGEM identifies itself as a legal entity as well as its level of permitted activity while still being a part of iGEM and synthetic biology across the nation is all very vague. It’s good that someone has an idea of how to investigate this feature of the problem terrain!
Group Photo
Attending the meeting on the Waterloo side…

oGEM Chat - Waterloo Side
Left to right in the above photo: Danielle, Andre, John, Leah.
Ed's Big Plans

