28 February 2013

Another "All Your Yesterdays" entry: Denisovan, or "Polar Neandertal"

They've extended the deadline for the All Your Yesterdays contest, so I've decided to do a couple more entries. I started this one years ago as a Neandertal restoration. Since that time, new genomic discoveries showed that the speculative pigmentation was incorrect. But, other discoveries identified a new candidate for the subject matter!

Known from a few scrappy pieces, the Siberian Denisovans (Homo sp. or Homo sapiens ssp., depending on how large you like your species) are a true challenge to reconstruct. We have their entire genome, but know almost nothing about their anatomy. The few fossil elements we have are not morphologically distinct from Neandertals (Homo neanderthalensis or Homo sapiens neanderthalensis) or humans (Homo sapiens sapiens).
But the genomic facts are highly intriguing:
  1. Some Oceanian humans have inherited up to 6% of their nuclear DNA from Denisovans (with the highest ratios in Meganesia [Australia and New Guinea]). 
  2. The nuclear DNA indicates a common ancestor with Neandertals, shortly after the split from proto-humans.
  3. But the mitochondrial DNA indicates a motherline that branched off much earlier. (Possibly Homo erectus?)
  4. Genes for pigments are consistent with dark skin.
Here I've imagined a Siberian Denisovan as a sort of "polar Neandertal". As with polar bears, his skin is dark, trapping heat, but his pelage is light, allowing for camouflage against the taiga and tundra. He is the last of his kind — his southern kin mixed with the strange, baby-faced people who keep invading from the west. But he does not welcome them. He will fight to his death.

27 February 2013

"Texan Mama", my "All Your Yesterdays" contest entry

I would have worked on this a bit longer, but the "All Your Yesterdays" contest deadline is tomorrow.
Texan Mama
Dimetrodon and its kin have often been described as "mammal-like reptiles", but in fact they they are just as closely related to modern reptiles as we are (in terms of shared descent). Creatures like Dimetrodon, Moschops, Lystrosaurus, Cynognathus, Morganucodon, etc. are more properly termed "stem-mammals", meaning that they are not mammals, but are more closely related to mammals than to any other living organisms.

We can infer, in the absence of direct evidence, that all stem-mammals probably possessed any characteristics shared by us mammals and our closest living non-mammalian relatives, the sauropsids: turtles, tuataras, lizards (including snakes), crocodylians, and birds. But mammalian characteristics not shared by sauropsids are trickier. When did hair evolve? When did lactation evolve? We have a few clues but no definite answers.

In this piece, I have pushed fur back to an extremely early time — Dimetrodon is one of the furthest stem-mammals from Mammalia proper. While we know that a later stem-mammal, Estemmenosuchus, had glandular skin without any sign of fur, it is possible that fur evolved earlier and was simply lost or reduced in some lineages, as it has been in many lineages of placental mammal.

I have also posited parental feeding, but not, strictly speaking, lactation. Other lineages of tetrapod, including caecilians and pigeons, have evolved ways of feeding the young from foodstuffs produced by the mother. The mother Dimetrodon's sides are swollen with nutritious substances which seep out as her pups gobble it up. Is it milk? Sort of and sort of not.

Finally, I have scrupulously avoided any suggestion that these are in any way reptilian. They do retain some plesiomorphies evidenced in some reptiles, amphibians, and lungfishes, such as a sprawling gait, belly scales, and acute color vision, but they lack the dry skin and derived scales of true reptiles. Not a single sauropsid texture was used in the photocollage; instead they have the textures of Hippopotamus, Phacochoerus, Procyon, Homo, Zaglossus, Caecilia, Litoria, and even Neoceratodus. These Dimetrodon are moist, glandular creatures — not reptiles at all.
If you're wondering, here's a quick breakdown of the textures used:
Hippopotamus amphibius (hippo)
general, especially mother's head and torso
Phacochoerus (warthog)
general, especially mother's tail and torso
Procyon (raccoon)
soles
Homo sapiens (human)
general, especially mother's sail
Zaglossus (long-beaked echidna)
juveniles' faces
Caecilia (caecilian)
mother's sides and underside
Litoria caerulea (Australian green tree frog)
general, especially mother's limbs
Neoceratodus forsteri (Queensland lungfish)
juveniles' underbelly
I've also submitted a variant, done in a Pop Art style inspired by Roy Lichtenstein's work, to the related Love in the Time of Chasmosaurs: All Yesterdays contest:


Note: Yes, I do descend from a long line of Texan mothers.

15 February 2013

JSEN: JavaScript Expression Notation

That idea I was talking about yesterday? Storing mathematical expressions as JSON? I went ahead and made it as a TypeScript project and released it on GitHub:


JavaScript Expression Notation (JSEN)



Still need to complete the unit test coverage and add a couple more features. I made a change from my original post to the syntax for namespace references. (The reason? I realized I needed to be able to use "*" as a local identifier for multiplication.) They work within Namespace declaration blocks, but I need to make them work at the higher level of Namespaces declaration blocks as well. (Done.) I also want to allow functions to be used as namespaces. (Done.)

This is possible right now:

jsen.decl('my-fake-namespace', {
   'js': 'http://ecma-international.org/ecma-262/5.1',

   'x': 10,
   'y': ['js:Array', 1, 2, 3],
   'z': ['js:[]', 'y', 1]
});

jsen.eval('my-fake-namespace', 'x'); // 10
jsen.eval('my-fake-namespace', 'y'); // [1, 2, 3]
jsen.eval('my-fake-namespace', 'z'); // 2

jsen.expr('my-fake-namespace', 'x'); // 10 // Deprecated
jsen.expr('my-fake-namespace', 'y'); // Deprecated
    // ["http://ecma-international.org/ecma-262/5.1:Array", 1, 2, 3]
jsen.expr('my-fake-namespace', 'z'); // Deprecated
    // ["http://ecma-international.org/ecma-262/5.1:[]", "y", 1]

Eventually something like this will be possible as well:

14 February 2013

Mathematical expressions as JSON (and phyloreferencing)

For Names on Nodes I did a lot of work with MathML (specifically MathML-Content), an application of XML for representing mathematical concepts. But now, as XML wanes and JSON waxes, I've started to look at ideas for porting Names on Nodes concepts over to JSON.

I've been drawing up a very basic and extensible way to interpret JSON mathematically. Each of the core JSON values translates like so:
  • Null, Boolean, and Number values are interpreted as themselves.
  • Strings are interpreted as qualified identifiers (if they include ":") or local identifiers (otherwise).
  • Arrays are interpreted as the application of an operation, where the first element is a string identifying the operation and the remaining elements are arguments.
  • Objects are interpreted either as:
    • a set of declarations, where each key is a [local] identifier and each value is an evaluable JSON expression (see above), or
    • a namespace, where each key is a URI and each value is a series of declarations (see previous).

Examples

Here's a simple object declaring some mathematical constants (approximately):

{
    "e": 2.718281828459045,
    "pi": 3.141592653589793
}

Supposing we had declared some operations (only possible in JavaScript, since JSON doesn't have functions) equivalent to those of MathML (whose namespace URI is "http://www.w3.org/1998/Math/MathML"), we could do this:

{
    "x":
        ["http://www.w3.org/1998/Math/MathML:plus",
            1,
            2
        ],
    "y":
        ["http://www.w3.org/1998/Math/MathML:sin",
            ["http://www.w3.org/1998/Math/MathML:divide",
                "http://www.w3.org/1998/Math/MathML:pi",
                2
            ]
        ]
}

Once evaluated, x would be 3 and y would be 1 (or close to it, given that this is floating-point math).

Now for the interesting stuff. Suppose we had declared Names on Nodes operations and some taxa using LSIDs:

{
    "Homo sapiens": "urn:lsid:ubio.org:namebank:109086",
    "Ornithorhynchus anatinus": "urn:lsid:ubio.org:namebank:7094675",
    "Mammalia":
        ["http://namesonnodes.org/ns/math/2013:clade",
            ["http://www.w3.org/1998/Math/MathML:union",
                "Homo sapiens",
                "Ornithorhynchus anatinus"
            ]
        ]
}

Voilá, a phylogenetic definition of Mammalia in JSON!

I think this could be pretty useful. My one issue is the repetition of  long URIs. It would be nice to have a mechanism to import them using shorter handles. Maybe something like this?

{
    "mathml":   "http://www.w3.org/1998/Math/MathML:*",
    "namebank": "urn:lsid:ubio.org:namebank:*",
    "NoN":      "http://namesonnodes.org/ns/math/2013:*",

    "Mammalia":
        ["NoN:clade",
            ["mathml:union",
                "namebank:109086",
                "namebank:7094675"
            ]
        ]
}

Something to ponder. Another thing to ponder: what should I call this? MathON? MaSON?

28 January 2013

Using TypeScript to Define JSON Data

JSON has gradually been wearing away at XML's position as the primary format for data communication on the Web. In some ways, that's a good thing: JSON is much more compact and readable. In other ways, it's not so great: JSON lacks some of XML's features.

One of these features is document type definitions. For XML, there are a variety of formats (DTD, XML Schema, RELAX NG, etc.) for specifying exactly what your XML data looks like: what are the tag names, possible attributes, etc. JSON is a lot more loosey-goosey here.

Okay, that's not entirely true: there is JSON Schema. I've never known anyone to use it, but it's there. It's awfully verbose, though. (So are the definitional formats for XML, but it's XML — you expect it!)

I was thinking about this the other day, and I realized that there is actually a great definitional format for JSON already in existence: TypeScript! If you haven't heard of it, TypeScript is a superset of JavaScript which introduces optional strict typing. And since JSON is a subset of JavaScript, TypeScript is applicable to JSON as well.

One of the great features of TypeScript is that interface implementation is implicit. In Java or ActionScript, you have to specifically say that a type "implements MyInterface". In TypeScript, if it fits, it fits. For example:

interface List
{
    length: number;
}

function isEmpty(list: List): bool
{
    return list.length === 0;
}

console.log(isEmpty("")); // true
console.log(isEmpty("foo")); // false
console.log(isEmpty({ length: 0 })); // true
console.log(isEmpty({ length: 3 })); // false
console.log(isEmpty({ size: 1})); // Compiler error!

(Note: for some reason that I can't fathom, isEmpty() doesn't work on arrays. Well, TypeScript is still in development — version 0.8.2 right now. Update: I filed this as a bug.)

Note that you can use interfaces even on plain objects. So of course you can use it to describe a JSON format. Here's an example from a project I hope to release before too long:

interface Model
{
    uid: string;
}

interface Name extends Model
{
    citationStart?: number;
    html?: string;
    namebankID?: string;
    root?: bool;
    string?: string;
    type?: string;
    uri?: string;
    votes?: number;
}

interface Taxon
{
    canonicalName?: Name;
    illustrated?: bool;
    names?: Name[];
}

Now, for example, I can declare that an API search method will return data as an array of Taxon objects (Taxon[]). And look how compact and readable it is!

Note that there is one drawback here: there is no way to enforce this at run-time. JSON Schema might be a better choice if that's what you need. But for compile-time checking and documentation, it's a pretty great tool.

24 January 2013

Saving Bootstrap Settings

The popular web page framework Bootstrap recently added a web form whereby you can customize visual settings (color scheme, fonts, etc.). Unfortunately they didn't add a way to save those settings, so if you later decide you need to tweak them and you didn't happen to just leave that web page open, you're screwed. You either have to reinvent them, go from memory, or dig through the generated files and hope you didn't miss anything.

I'm sure they plan to address this eventually, but in the meantime I created some JavaScript code to work around this: https://gist.github.com/4628506

To use this code:
  1. Go to: http://twitter.github.com/bootstrap/customize.html
  2. Run the script in the JavaScript console. (If you don't use a browser with a JavaScript console, you're beyond my help.)
  3. Fill out the customization form.
  4. You can record your settings into an object by running: var settings = record()
  5. You can grab those as JSON by running: JSON.stringify(settings)
  6. You can reinstate those settings later by running: play(settings)
  7. You can save your settings to local storage by running: save()
  8. You can retrieve your settings from local storage by running: retrieve()
I haven't fully tested this, so let me know if you run into any issues.

SIDE NOTE: This is my first gist!



02 January 2013

All Known Great Ape Individuals (Messinian to Present)

Happy 2013, everyone!

Recently I announced a code package I was working on, called Haeckel, for generating vector-based charts related to evolutionary biology. Here's an image I've created using it:

Known Great Ape Individuals
This chart represents all known hominid individuals (Hominidae = great apes, including humans and stem-humans) from the Messinian to the present, erring on the conservative side when the material is too poor to determine the exact number.

If you've been following this blog for a few years you may remember an earlier version of this. I've done a lot of refinement to the data since then. The earlier versions were dissatisfying to me because the horizontal axis was essentially arbitrary. For this version I used matrices from a phylogenetic analysis (Strait and Grine 2004, Table 3 and Appendix C) of craniodental characters to generate a distance matrix, and then inferred positions for other taxa based on phylogenetic proximity and containing clade. This is similar to the metric I used in this chart, except that it incorporates Appendix C, uses inference, and averages distance from humans against distance from [Bornean] orangutans. Don't be mistaken — this is still arbitrary. But it's a bit closer to something real.

Stray notes:
  • I'm pretty sure there are Pliocene stem-orangutans somewhere, right? Might have some work left to do on that data.
  • The dot with no taxon above "Australopithecus" is an indeterminate stem-human from Laetoli. It should probably go further left.
  • The Ardipithecus bubble includes the poorly-known "Australopithecus" praegens. (Although in some runs it moves outside — there's a random element to the plotting.)
  • The Holocene is barely visible up at the top. What a worthless epoch.
  • Homo floresiensis (hobbits) are far to the left of Homo sapiens because I placed them outside Clade(Homo erectus ∪ Homo sapiens).
  • You may recall Lufengpithecus? wushanensis as "Wushan Man", as it was originally placed in Homo erectus. (Hey, it's just teeth.)
  • A couple of fossil chimpanzees, lots of fossil orangutans, but no fossil gorillas. :(
    • (Unless you count Chororapithecus, but that's pre-Messinian. Very pre-Messinian. Suspiciously pre-Messinian....)
  • Look at all that overlap between Homo, Paranthropus, and Australopithecus!
    • I have a feeling, though, that if I added another dimension, Paranthropus and Homo would jut out in opposite directions.
    • Reclassifying Australopithecus sediba as Homo sediba would also decrease the overlap. (Although its position is inferred — actually scoring it might do the same thing.)
    • It's frustrating that the type species of Australopithecus and Paranthropus are also just about the most similar species across the two genera.
  • Kenyanthropus and Praeanthropus have been provisionally sunk into Australopithecus.
  • Should we just sink Orrorin and Sahelanthropus into Ardipithecus? Why not?
  • My guess is that if I added postcranial characters, the stem-humans would all shift right (humanward). Oh, for a good matrix of postcranial characters....
Update
Oh yeah, and if you want a peek at the data, go here.