31 May 2007

Google Developer Day France 2007

Today, I attended the french session of the Google Developer Day at Paris. Most of the conference dealt with the 33 (!) google APIs , mashups and the last (and most interesting) was about the google web toolkit. The place was full of testosterone and, sorry, nothing about science (scholar...).

Patrick Chenzon made a general introduction about the google APIs. He also wrote a short demo on how to create a mashup with the map API.
http://wordpress.chanezon.com/
http://del.icio.us/chanezon

Gears was introduced (the buzz word of the day) with a demo using reader.google.com

David Aubespin talked about the google gadget. (I've already used this technology with pubmed , see google-gadget-for-bioinformatics.html)
There is now a scratchpad to edit and test your gadget. We also had a presentation about the new gadget system now used within google maps: mapplets. For example my NCBI gadget could be modified to extract the content of the <Affiliation> tag, getting the latitude and longitude of this address and display it on the map.


Jean François Wassong talked about the google map API. There is also a new tool , the Mashup Editor an AJAX development framework and a set of tools that enable developers to quickly and easily create simple web applications and mashups with Google services like Google Maps and Google Base.

For the last talk Didier Girard spoked about the google web toolkit. He created example on how to create an AJAX based interface using the GWT, he also used GWT Designer to design the graphical interface.


Pierre

25 May 2007

Public Gene Ontology MySQL Mirror Now Available

Via the Go newsletter.
A public Gene Ontology MySQL mirror at the EBI now offers a remote connection to a regularly updated mirror of the GO schema.
Connection details are:


  • user: go_select

  • password:amigo

  • host: mysql.ebi.ac.uk

  • port: 4085


example:
mysql -hmysql.ebi.ac.uk -ugo_select -pamigo -P4085 latest_go -e 'select concat(left(name,20),"...") as name,term_type,acc from term where acc like "GO:%" limit 20'
+-------------------------+--------------------+------------+
| name | term_type | acc |
+-------------------------+--------------------+------------+
| mitochondrion inheri... | biological_process | GO:0000001 |
| mitochondrial genome... | biological_process | GO:0000002 |
| reproduction... | biological_process | GO:0000003 |
| ribosomal chaperone ... | molecular_function | GO:0000005 |
| high affinity zinc u... | molecular_function | GO:0000006 |
| low-affinity zinc io... | molecular_function | GO:0000007 |
| thioredoxin... | molecular_function | GO:0000008 |
| alpha-1,6-mannosyltr... | molecular_function | GO:0000009 |
| trans-hexaprenyltran... | molecular_function | GO:0000010 |
| vacuole inheritance... | biological_process | GO:0000011 |
| single strand break ... | biological_process | GO:0000012 |
| single-stranded DNA ... | molecular_function | GO:0000014 |
| phosphopyruvate hydr... | cellular_component | GO:0000015 |
| lactase activity... | molecular_function | GO:0000016 |
| alpha-glucoside tran... | biological_process | GO:0000017 |
| regulation of DNA re... | biological_process | GO:0000018 |
| regulation of mitoti... | biological_process | GO:0000019 |
| negative regulation ... | biological_process | GO:0000020 |
| mitotic spindle elon... | biological_process | GO:0000022 |
| maltose metabolic pr... | biological_process | GO:0000023 |
+-------------------------+--------------------+------------+

22 May 2007

Is there any XMP in scientific pdf ? (No)

Roderic Page from iPhylo has introduced XMP in his blog. XMP is an Adobe format used to store metadata in files, such as PDFs. Adobe also provides an API to extract the XMP from the files.

I've downloaded the toolkit to see if any meta information could be extracted from the scientific papers. The adobe toolkit needs expat (a XML parser) to be installed and it comes with a sample application 'DumpScannedXMP' finding all XMP Packets in a file and printing their content.

I've tested this with some papers found on the net.
./target/i80386linux/debug/DumpScannedXMP 3851.pdf
RoXaN, a Novel Cellular Protein Containing TPR, LD, and Zinc Finger Motifs, Forms a Ternary Complex with Eukaryotic Initiation Factor 4G and Rotavirus NSP3: from Journal of Virology 2003

// ==============================================================

// Dumping raw input for "/home/pierre/3851.pdf" (879724..881254)

<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="3.1-701">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:xap="http://ns.adobe.com/xap/1.0/">
<xap:CreateDate>2004-03-16T15:35:47Z</xap:CreateDate>
<xap:CreatorTool>XPP</xap:CreatorTool>
<xap:ModifyDate>2007-05-22T12:24:37Z</xap:ModifyDate>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:format>application/pdf</dc:format>
<dc:description>
<rdf:Alt>
<rdf:li xml:lang="x-default"/>
</rdf:Alt>
</dc:description>
<dc:creator>
<rdf:Seq>
<rdf:li/>
</rdf:Seq>
</dc:creator>
<dc:title>
<rdf:Alt>
<rdf:li xml:lang="x-default"/>
</rdf:Alt>
</dc:title>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
<pdf:Keywords/>
<pdf:Producer/>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/">
<xapMM:DocumentID>uuid:e0500da6-1dd1-11b2-0a00-ecd00f090858</xapMM:DocumentID>
<xapMM:InstanceID>uuid:e0500db1-1dd1-11b2-0a00-000000004869</xapMM:InstanceID>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="r"?>

Dumping XMPMeta object "" (0x0)

http://ns.adobe.com/xap/1.0/ xap: (0x80000000 : schema)
xap:CreateDate = "2004-03-16T15:35:47Z"
xap:CreatorTool = "XPP"
xap:ModifyDate = "2007-05-22T12:24:37Z"

http://purl.org/dc/elements/1.1/ dc: (0x80000000 : schema)
dc:format = "application/pdf"
dc:description (0x1E00 : isLangAlt isAlt isOrdered isArray)
[1] = "" (0x50 : hasLang hasQual)
? xml:lang = "x-default" (0x20 : isQual)
dc:creator (0x600 : isOrdered isArray)
[1] = ""
dc:title (0x1E00 : isLangAlt isAlt isOrdered isArray)
[1] = "" (0x50 : hasLang hasQual)
? xml:lang = "x-default" (0x20 : isQual)

http://ns.adobe.com/pdf/1.3/ pdf: (0x80000000 : schema)
pdf:Keywords = ""
pdf:Producer = ""

http://ns.adobe.com/xap/1.0/mm/ xapMM: (0x80000000 : schema)
xapMM:DocumentID = "uuid:e0500da6-1dd1-11b2-0a00-ecd00f090858"
xapMM:InstanceID = "uuid:e0500db1-1dd1-11b2-0a00-000000004869"

Pretty serialization, 1478 bytes :

<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Public XMP Toolkit Core 3.5">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:xap="http://ns.adobe.com/xap/1.0/">
<xap:CreateDate>2004-03-16T15:35:47Z</xap:CreateDate>
<xap:CreatorTool>XPP</xap:CreatorTool>
<xap:ModifyDate>2007-05-22T12:24:37Z</xap:ModifyDate>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:format>application/pdf</dc:format>
<dc:description>
<rdf:Alt>
<rdf:li xml:lang="x-default"/>
</rdf:Alt>
</dc:description>
<dc:creator>
<rdf:Seq>
<rdf:li/>
</rdf:Seq>
</dc:creator>
<dc:title>
<rdf:Alt>
<rdf:li xml:lang="x-default"/>
</rdf:Alt>
</dc:title>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
<pdf:Keywords/>
<pdf:Producer/>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/">
<xapMM:DocumentID>uuid:e0500da6-1dd1-11b2-0a00-ecd00f090858</xapMM:DocumentID>
<xapMM:InstanceID>uuid:e0500db1-1dd1-11b2-0a00-000000004869</xapMM:InstanceID>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>

Compact serialization, 990 bytes :

<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Public XMP Toolkit Core 3.5">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:xap="http://ns.adobe.com/xap/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:pdf="http://ns.adobe.com/pdf/1.3/"
xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/"
xap:CreateDate="2004-03-16T15:35:47Z"
xap:CreatorTool="XPP"
xap:ModifyDate="2007-05-22T12:24:37Z"
dc:format="application/pdf"
pdf:Keywords=""
pdf:Producer=""
xapMM:DocumentID="uuid:e0500da6-1dd1-11b2-0a00-ecd00f090858"
xapMM:InstanceID="uuid:e0500db1-1dd1-11b2-0a00-000000004869">
<dc:description>
<rdf:Alt>
<rdf:li xml:lang="x-default"/>
</rdf:Alt>
</dc:description>
<dc:creator>
<rdf:Seq>
<rdf:li/>
</rdf:Seq>
</dc:creator>
<dc:title>
<rdf:Alt>
<rdf:li xml:lang="x-default"/>
</rdf:Alt>
</dc:title>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>


A test with a more recent paper RNAmmer: consistent and rapid annotation of ribosomal RNA genes . NAR 2007 contains as much information.

So is there any interesting XMP in scientific pdf ? no.


Pierre

18 May 2007

A filter for RSS feeds

Stew has introduced the google-code-project where is hosted OpenRevien (the source code of Postgenomic). This gave me the idea to host feedfilter a program filtering rss feeds that I wrote quickly a few days ago. My project is hosted at http://code.google.com/p/feedfilter/. It's a small java program running as a CGI (you don't need tomcat or either..). A parameter in the cgi is used to filter the feeds:

Examples:

PNAS - RSS feed of Early Edition articles: keep posts containing the word "protein"
feed("http://www.pnas.org/rss/ahead.xml",contains("protein"))


PNAS - RSS feed of Early Edition articles: keep posts NOT containing the words "[IMMUNOLOGY]" or "[geology]"
feed("http://www.pnas.org/rss/ahead.xml",NOT(OR(contains("[IMMUNOLOGY]"),contains("[geology]"))))

RSS feeds from connotea about tag=bioinformatics where author is not dc:creator=lindenb
feed("http://www.connotea.org/rss/tag/bioinformatics",not(equals("dc:creator","lindenb")))

Syntax
input: feed( <url:string>, <node> )
node: AND( <node> , <node> )
| OR( <node> , <node> )
| NOT( <node> )
| contains( <qName:string>,<value:string>)
| contains( <value:string>)
| equals( <qName:string>,<value:string>)
| equals( <value:string>)
| regex( <qName:string>,<java regular expression:string>)
| regex( <java regular expression:string>)




Pierre

17 May 2007

Wilkinson's "The Declaration of Semantic Web Independence"

Mark Wilkison has posted a :

Declaration of Semantic Web Independence



For more details see: ttp://biordf.org/wilkinsonlab/index.php/all/2007/05/17/semantic_declaration_of_independence



  1. Ontologies are a path to a goal, not the goal itself.
    • Ontologies are World Views
    • World Views are Hypotheses
    • Hypotheses are Queries
    • Queries are Disposable
    • Therefore Ontologies are (should be) Disposable!

  2. Reasoning is your problem, not mine!

  3. LSIDs provide a great way of solving the ontology-segmentation problem

  4. Ontological predicates can be thought of as, and mapped to, Web Service

FLEX, Flash and Bioinformatics: episode II

Looking for resources about flash/flex and biofinformatics I found this nice (action)script example querying pubmed:

www: http://codelog.voisen.org
Here is the flash application
Here is the the source code

Pierre

16 May 2007

Health Care, Life Sciences and the Semantic Web: Publication

From the W3C:

The Semantic Web Health Care and Life Sciences Interest Group (HCLSIG) has reached a significant milestone with their publication of the article "Advancing Translational Research with the Semantic Web." This joint work of the Interest Group was published in BMC Bioinformatics, a peer-reviewed open access journal that plays a central role in the bioinformatics community. The authors illustrate the value of Semantic Web technologies to neuroscience researchers and biomedicine and report on several projects by members of the Interest Group.

15 May 2007

Exploring the 'Nature Network': SVG javascript foaf JSON XHTML

The Freebase API uses JSON as a support for its query langage. I only knew a few things about JSON but its was the first time I used it. I then wanted to learn how to use it with dynamic html: my own little private project was to try to built what I did with java about one year ago with http://www.urbigene.com/foafexplorer/: browsing a social scientific

myfoafexplorer



But this time I just wanted to use client technologies and my source of data was Nature Network (hot topic !)
The first point was to fetch the data. I wrote a simple java parser which downloaded recursively all the profiles and groups starting from my own profile. I ignored a few pages containing some xml errors: http://network.nature.com/profile/U078528F5: HTML parser error : htmlParseEntityRef: expecting ';' PubMed ID:(Museums&Web). My first idea was then to export this to FOAF

nn.rdf.
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xm
lns:foaf="http://xmlns.com/foaf/0.1/" xmlns:nn="http://network.na
ture.com/" xmlns:dc="http://purl.org/dc/elements/1.1/">
<foaf:Person rdf:about="http://network.nature.com/profile/U78424D59">

<foaf:Person rdf:about="http://network.nature.com/profile/lindenb">
<foaf:name>Lindenbaum Pierre</foaf:name>
<nn:job>Bioinformatician</nn:job>
<nn:affiliation>Integragen SA</nn:affiliation>
<foaf:weblog rdf:resource="http://plindenbaum.blogspot.com"/>
<foaf:img rdf:resource="http://network.nature.com/assets/user/000/000/037/large.png"/>
<dc:subject>computational</dc:subject>
<dc:subject>nnb</dc:subject>
<dc:subject>computational biology</dc:subject>
<dc:subject>network</dc:subject>
</foaf:Person>

(...)

<foaf:Group rdf:about="http://network.nature.com/group/bioinformatics">
<foaf:name>Bioinformatics</foaf:name>
<foaf:member rdf:resource="http://network.nature.com/profile/U7457FA5D"/>
<foaf:member rdf:resource="http://network.nature.com/profile/UAD17B888"/>
<foaf:member rdf:resource="http://network.nature.com/profile/U438F4261"/>
<foaf:member rdf:resource="http://network.nature.com/profile/U579CAC72"/>
</foaf:Group>

(...)

<nn:Connection rdf:nodeId="5">
<nn:contact rdf:resource="http://network.nature.com/profile/U2570065B"/>
<nn:contact rdf:resource="http://network.nature.com/profile/UDC37FBCB"/>
</nn:Connection>
<nn:Connection rdf:nodeId="6">
<nn:contact rdf:resource="http://network.nature.com/profile/UAB504518"/>
<nn:contact rdf:resource="http://network.nature.com/profile/UDC691EA2"/>
</nn:Connection>
(...)



I then transformed this rdf file into JSON using the following XSLT stylesheet.
foaf2json.xsl
<?xml version='1.0' ?>
<xsl:stylesheet
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:nn="http://network.nature.com/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
version='1.0'>
<xsl:output method='text'/>

<xsl:template match="rdf:RDF">
var network= {
"profile":[
<xsl:for-each select='foaf:Person'>
{
"id": &quot;<xsl:value-of select="substring(@rdf:about,35)"/>&quot;,
"name":&quot;<xsl:value-of select="foaf:name"/>&quot;,
"job":&quot;<xsl:value-of select="nn:job"/>&quot;,
"affiliation":&quot;<xsl:value-of select="nn:affiliation"/>&quot;,
"www":&quot;<xsl:value-of select="foaf:weblog/@rdf:resource"/>&quot;,
"img":&quot;<xsl:value-of select="foaf:img/@rdf:resource"/>&quot;,
"tags":[<xsl:for-each select='dc:subject'>&quot;<xsl:value-of
select="."/>&quot;<xsl:if
test="position()!=last()">,</xsl:if></xsl:for-each>],
"pos":{"x":0,"y":0},
"goal":{"x":0,"y":0},
"g":null
}
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
],
"group":[
<xsl:for-each select='foaf:Group'>
{
"uri": &quot;<xsl:value-of select="substring(@rdf:about,33)"/>&quot;,
"name":&quot;<xsl:value-of select="foaf:name"/>&quot;,
"members":[<xsl:for-each select='foaf:member'>&quot;<xsl:value-of
select="substring(@rdf:resource,35)"/>&quot;<xsl:if
test="position()!=last()">,</xsl:if></xsl:for-each>] }
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
],
"link":[
<xsl:for-each select='nn:Connection'>
[&quot;<xsl:value-of
select="substring(nn:contact[1]/@rdf:resource,35)"/>&quot;,&quot;<xsl:value-of
select="substring(nn:contact[2]/@rdf:resource,35)"/>&quot;]<xsl:if
test="position()!=last()">,</xsl:if>
</xsl:for-each>
]
};
</xsl:template>
</xsl:stylesheet>


This gave me my json.js.

var network= {
"profile":[
{
"id": "lindenb",
"name":"Lindenbaum Pierre",
"job":"Bioinformatician",
"affiliation":"Integragen SA",
"www":"http://plindenbaum.blogspot.com",
"img":"http://network.nature.com/assets/user/000/000/037/large.png",
"tags":["computational","nnb","computational biology","network","science","cgh","social","rdf","virology","wiki","biology","lims","rotavirus","networking","protocol","c","gene ontoloy","community","semantic","web","molecular biology","linux","ontology","semantic web","social network","java","bioinformatics","microarray"
],
"pos":{"x":0,"y":0},
"goal":{"x":0,"y":0},
"g":null
}
},
(...)


What is cool with JSON is that this format stores the data but and it is also a big javascript object which can be used just like a regular variable.

The result is available here: http://www.urbigene.com/nn/network.xml.
Each object profile, displayed with a SVG icon, contains the position of the current icon (profile[n].pos.x, profile[n].pos.y) and the position where the icon should move (profile[n].goal.x, profile[n].goal.y). Each time an icon/tag/profile/job/affiliation/group is clicked, a function nextStep is ivoked. This function calls the setTimeout method where each icon is moved sightly to its goal. This function calls itself recursively until all icons have reached their goal. This page was tested using Firefox 2.0.



Updated 2010-08-12 : source code

foaf2json.xsl

<?xml version='1.0' ?>
<xsl:stylesheet
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:nn="http://network.nature.com/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
version='1.0'>
<xsl:output method='text'/>

<xsl:template match="rdf:RDF">
var network= {
"profile":[
<xsl:for-each select='foaf:Person'>
{
"id": &quot;<xsl:value-of select="substring(@rdf:about,35)"/>&quot;,
"name":&quot;<xsl:value-of select="foaf:name"/>&quot;,
"job":&quot;<xsl:value-of select="nn:job"/>&quot;,
"affiliation":&quot;<xsl:value-of select="nn:affiliation"/>&quot;,
"www":&quot;<xsl:value-of select="foaf:weblog/@rdf:resource"/>&quot;,
"img":&quot;<xsl:value-of select="foaf:img/@rdf:resource"/>&quot;,
"tags":[<xsl:for-each select='dc:subject'>&quot;<xsl:value-of
select="."/>&quot;<xsl:if
test="position()!=last()">,</xsl:if></xsl:for-each>],
"pos":{"x":0,"y":0},
"goal":{"x":0,"y":0},
"g":null
}
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
],
"group":[
<xsl:for-each select='foaf:Group'>
{
"uri": &quot;<xsl:value-of select="substring(@rdf:about,33)"/>&quot;,
"name":&quot;<xsl:value-of select="foaf:name"/>&quot;,
"members":[<xsl:for-each select='foaf:member'>&quot;<xsl:value-of
select="substring(@rdf:resource,35)"/>&quot;<xsl:if
test="position()!=last()">,</xsl:if></xsl:for-each>] }
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
],
"link":[
<xsl:for-each select='nn:Connection'>
[&quot;<xsl:value-of
select="substring(nn:contact[1]/@rdf:resource,35)"/>&quot;,&quot;<xsl:value-of
select="substring(nn:contact[2]/@rdf:resource,35)"/>&quot;]<xsl:if
test="position()!=last()">,</xsl:if>
</xsl:for-each>
]
};
</xsl:template>



</xsl:stylesheet>



network.xml

<html
xmlns="http://www.w3.org/1999/xhtml"
>
<head>
<title>Nature Network With SVG: Pierre Lindenbaum</title>

<script type="text/javascript" src="nn.js"/>
<script type="text/javascript"><![CDATA[
/** the HTML namespace */
var HTML={
"NS":"http://www.w3.org/1999/xhtml"
};
/** the SVG namespace */
var SVG={
"NS":"http://www.w3.org/2000/svg"
};
/** the XLINK namespace */
var XLINK={
"NS":"http://www.w3.org/1999/xlink"
};


/** the html document */
var htmldoc=null;
/** the svg root */
var svgroot=null;
/** map uri2user */
var uri2user= new Array();
/** animation running */
var animated=false;
/** screen width */
var viewWidth=0.0;
/** ratio for animation */
var RATIO_ANIME=0.8;
/** time for animated */
var ELAPSED_TIME=10;

/** initialise the whole document */
function init()
{
htmldoc= this.document;
svgroot= document.getElementById("svgdoc");
var svgrect =document.getElementById("frameSVGRect");

viewWidth=this.innerWidth-30;

svgrect.setAttribute("width",viewWidth);
svgrect.setAttribute("height",this.innerHeight-100);
svgroot.setAttribute("width",1+viewWidth);
svgroot.setAttribute("height",1+this.innerHeight-100);

var v= network.profile;
var cosf= Math.cos;
var sinf= Math.sin;

//loop over users
for(var i=0;i< v.length;++i)
{
//initialize the uri2user array
uri2user[v[i].id]=v[i];
var angle= Math.random()*6.2;
v[i].pos.x= this.innerWidth/2.0 + this.innerWidth*cosf(angle);
v[i].pos.y= this.innerHeight/2.0 + this.innerHeight*sinf(angle);
var g = htmldoc.createElementNS(SVG.NS,"g");
v[i].g = g;
g.setAttribute("title",v[i].name+" "+v[i].job+" "+v[i].affiliation);
g.setAttribute("onmousedown","focusProfile(this);");
g.setAttribute("transform","translate(-50,-50)");
g.setAttribute("cursor","pointer");
g.setAttribute("id",v[i].id);
var r1= htmldoc.createElementNS(SVG.NS,"rect");
r1.setAttribute("x",0);
r1.setAttribute("y",0);
r1.setAttribute("width",41);
r1.setAttribute("height",50);
r1.setAttribute("fill","gray");
r1.setAttribute("stroke","black");
g.appendChild(r1);

if(v[i].img.length>0)
{
var img= htmldoc.createElementNS(SVG.NS,"image");
img.setAttributeNS(XLINK.NS,"xlink:href",v[i].img);
img.setAttribute("x",4);
img.setAttribute("y",4);
img.setAttribute("width",41-8);
img.setAttribute("height",50-8);
g.appendChild(img);
}
else
{

}
svgroot.appendChild(g);
}
focusProfileID("lindenb");
}

function focusProfile(g)
{
focusProfileID(g.id);
}

function createProfileShown()
{
var profileShown= new Array();
var v= network.profile;
for(var i=0;i< v.length;++i)
{
profileShown[v[i].id]=0;
}
return profileShown;
}

function focusProfileID( id)
{
if(animated) return;
showLayer("profileLayer");
var profileShown= createProfileShown();



profileShown[id]=1;

var user=uri2user[id];
if(user==null) return;
var a=null;
var tag = document.getElementById("profileImg");
if(user.img.length==0)
{
tag.setAttribute("src","http://network.nature.com/images/user_generic_large.gif");
}
else
{
tag.setAttribute("src",user.img);
}
tag = document.getElementById("profileAnchor");
tag.setAttribute("href","http://network.nature.com/profile/"+user.id);
tag.setAttribute("title","Go to http://network.nature.com/profile/"+user.id);
tag.setAttribute("target",user.id);

tag = document.getElementById("profileName");
tag.innerHTML= user.name;
tag = document.getElementById("profileJob");
tag.innerHTML="";
a= htmldoc.createElementNS(HTML.NS,"a");
tag.appendChild(a);
a.setAttribute("href","javascript:focusJob(\""+user.job+"\");");
a.setAttribute("title",user.job);
a.appendChild(htmldoc.createTextNode(user.job));


tag = document.getElementById("profileAffiliation");
tag.innerHTML="";
a= htmldoc.createElementNS(HTML.NS,"a");
tag.appendChild(a);
a.setAttribute("href","javascript:focusAffiliation(\""+user.affiliation+"\");");
a.setAttribute("title",user.affiliation);
a.appendChild(htmldoc.createTextNode(user.affiliation));


tag = document.getElementById("profileWWW");
tag.innerHTML= ""
if(user.www.length>0)
{
a= htmldoc.createElementNS(HTML.NS,"a");
tag.appendChild(a);
a.setAttribute("href",user.www);
a.setAttribute("title",user.www);
a.setAttribute("target",user.www);
a.appendChild(htmldoc.createTextNode(user.www));
}
tag = document.getElementById("profileTags");
tag.innerHTML= ""
for(var i=0;i< user.tags.length;i++)
{
var a= htmldoc.createElementNS(HTML.NS,"a");
tag.appendChild(a);
a.setAttribute("href","javascript:focusTag(\""+user.tags[i]+"\");");
a.setAttribute("title",user.tags[i]);
a.appendChild(htmldoc.createTextNode(user.tags[i]));
if(i+1!= user.tags.length) tag.appendChild(htmldoc.createTextNode(" "));
}

var link=network.link;
for(var i=0;i< link.length;++i)
{
var L= link[i];
var other=null;
if(L[0]==id)
{
other =uri2user[L[1]];
}
else if(L[1]==id)
{
other =uri2user[L[0]];
}
if(other==null) continue;
profileShown[other.id]=1;
}

tag = document.getElementById("profileGroups");
tag.innerHTML= ""
var group=network.group;
for(var i=0;i< group.length;++i)
{
for(var j=0;j< group[i].members.length;++j)
{
if( group[i].members[j]==id)
{
var a= htmldoc.createElementNS(HTML.NS,"a");
tag.appendChild(a);
a.setAttribute("href","javascript:focusGroupID(\""+group[i].uri+"\");");
a.setAttribute("title",group[i].name);
a.appendChild(htmldoc.createTextNode(group[i].name));
tag.appendChild(htmldoc.createTextNode(" "));
break;
}
}
}
launchAnimation(profileShown);
}


function focusGroupID(id)
{
if(animated) return;
showLayer("groupLayer");
var group=network.group;
tag = document.getElementById("groupLayer");
tag.innerHTML= ""
for(var i=0;i< group.length;++i)
{
if(group[i].uri!=id) continue;
var e= htmldoc.createElementNS(HTML.NS,"b");
e.appendChild(htmldoc.createTextNode("Group: "));
tag.appendChild(e);
var e= htmldoc.createElementNS(HTML.NS,"a");
e.setAttribute("href","http://network.nature.com/group/"+group[i].uri);
e.setAttribute("title","http://network.nature.com/group/"+group[i].uri);
e.setAttribute("target",group[i].uri);
e.appendChild(htmldoc.createTextNode(group[i].name));
tag.appendChild(e);

var profileShown= createProfileShown();
for(var j=0;j< group[i].members.length;++j)
{
profileShown[group[i].members[j]]=1;
}


break;
}
launchAnimation(profileShown);
}

function focusTag(id)
{
if(animated) return;
showLayer("tagLayer");

tag = document.getElementById("tagLayer");
tag.innerHTML= ""
var e= htmldoc.createElementNS(HTML.NS,"b");
e.appendChild(htmldoc.createTextNode("Tag: "));
tag.appendChild(e);
tag.appendChild(htmldoc.createTextNode(id));

var profileShown= createProfileShown();

var v= network.profile;
id=id.toLowerCase();
for(var i=0;i< v.length;++i)
{
var t=v[i].tags;
for(var j=0;j< t.length;++j)
{
if(t[j].toLowerCase()==id)
{
profileShown[v[i].id]=1;
break;
}
}
}
launchAnimation(profileShown);
}


function focusJob(id)
{
if(animated) return;
showLayer("jobLayer");

tag = document.getElementById("jobLayer");
tag.innerHTML= ""
var e= htmldoc.createElementNS(HTML.NS,"b");
e.appendChild(htmldoc.createTextNode("Job : "));
tag.appendChild(e);
tag.appendChild(htmldoc.createTextNode(id));
focusOnProperty("job",id);
}

function focusAffiliation(id)
{
if(animated) return;
showLayer("affiliationLayer");

tag = document.getElementById("affiliationLayer");
tag.innerHTML= ""
var e= htmldoc.createElementNS(HTML.NS,"b");
e.appendChild(htmldoc.createTextNode("Affiliation : "));
tag.appendChild(e);
tag.appendChild(htmldoc.createTextNode(id));
focusOnProperty("affiliation",id);
}

function focusOnProperty(prop,id)
{
var profileShown= createProfileShown();
var v= network.profile;
id=id.toLowerCase();
for(var i=0;i< v.length;++i)
{
var p = v[i][prop].toLowerCase();
if(p==id)
{
profileShown[v[i].id]=1;
}
}
launchAnimation(profileShown);
}


function showLayer(id)
{
var a=["profileLayer","groupLayer","tagLayer","affiliationLayer","jobLayer"];
for(var i=0;i< a.length;i++)
{
document.getElementById(a[i]).style.visibility=(a[i]==id?"visible":"hidden");
}
}


function launchAnimation(profileShown)
{
if(animated) return;
var v= network.profile;
var x=5;
var y=5;
var cosf= Math.cos;
var sinf= Math.sin;
//loop over users
for(var i=0;i< v.length;++i)
{
if(profileShown[v[i].id]==1)
{
v[i].goal.x=x;
v[i].goal.y=y;
x+=(5+41);
if(x+41>viewWidth)
{
x=5;
y+=(5+50);
}
}
else
{
var angle= Math.random()*6.2;
v[i].goal.x= this.innerWidth/2.0 + this.innerWidth*cosf(angle);
v[i].goal.y= this.innerHeight/2.0 + this.innerHeight*sinf(angle);
}

}

animated=true;
setTimeout('nextStep()', ELAPSED_TIME);
}


function nextStep()
{
if(animated==false) return;
var continueAnimation=0;
var v= network.profile;
var sqrt= Math.sqrt;
for(var i=0;i< v.length;++i)
{
var curr=v[i];
var x0= curr.pos.x;
var y0= curr.pos.y;
var x1= curr.goal.x;
var y1= curr.goal.y;

var dx= x1-x0;
var dy= y1-y0;

curr.pos.x = x0+ (dx-dx*RATIO_ANIME);
curr.pos.y = y0+ (dy-dy*RATIO_ANIME);

dx= x1-x0;
dy= y1-y0;
var dist = sqrt(dx*dx+dy*dy);

if(dist<4)
{
curr.pos.x= x1;
curr.pos.y= y1;
}
else
{
continueAnimation++;
}
v[i].g.setAttribute("transform","translate("+ v[i].pos.x+","+v[i].pos.y+")");
}
if(continueAnimation>0)
{
setTimeout('nextStep()', ELAPSED_TIME);
}
else
{
animated=false;
}
}



]]></script>

</head>
<body onload="init()">
<div style="font-size:10pt;"><span style="font-size:18pt;"><b>The Nature Network</b></span> created by <a href="http://plindenbaum.blogspot.com">Pierre Lindenbaum PhD 2007</a>. <cite>Learning a little more javascript and <a href="http://en.wikipedia.org/wiki/JSON">JSON</a> I've used the <a href="nn.js">data</a> available from the <a href="http://network.nature.com/">Nature Network</a> on May 13, 2007 to display an interactive map of the network based on <a href="http://www.w3.org/Graphics/SVG/">SVG</a>, <a href="http://en.wikipedia.org/wiki/JSON">JSON</a> and javascript</cite>. This page was tested on <a href="http://www.mozilla.com/en-US/firefox/">Firefox 2</a></div>
<div id="layers" style="position:relative;width:100%; height:100px; background:lightgray;">

<div id="groupLayer" style="position:absolute; top:0px; left:0px;width:100%;visibility:hidden; "/>
<div id="tagLayer" style="position:absolute; top:0px; left:0px;width:100%;visibility:hidden; "/>
<div id="jobLayer" style="position:absolute; top:0px; left:0px;width:100%;visibility:hidden; "/>
<div id="affiliationLayer" style="position:absolute; top:0px; left:0px;width:100%;visibility:hidden; "/>
<div id="profileLayer" style="position:absolute; top:0px; left:0px;width:100%; font-size:9pt;">
<table width="100%"><tr>
<td width="33">
<a id="profileAnchor">
<img id="profileImg" width="33" height="42" src="http://network.nature.com/images/user_generic_large.gif"/>
</a>
</td>
<td>
<b>Name :</b> <span id="profileName"></span>
<b>Job :</b> <span id="profileJob"></span>
<b>Affiliation :</b> <span id="profileAffiliation"></span>
<b>www :</b> <span id="profileWWW"></span>
<b>Tags :</b> <span id="profileTags"></span>
<b>Groups :</b> <span id="profileGroups"></span>
</td></tr></table></div>

</div><br/>
<svg id="svgdoc" xmlns="http://www.w3.org/2000/svg" version="1.1" width="100" height="100">
<defs>
<linearGradient id = "gradient1" x1 = "50%" y1 = "0%" x2 = "50%" y2 = "100%">
<stop stop-color = "white" offset = "0%"/>
<stop stop-color = "black" offset = "100%"/>
</linearGradient>
</defs>

<rect id="frameSVGRect" x="0" y="0" width="100" height="100" fill="lightgray" stroke="black"/>

</svg>
<div>Pierre Lindenbaum: plindenbaum ( a t ) yahoo ( d o t ) fr </div>

<!-- google analytics -->

<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "XXXX-2";
urchinTracker();
</script>

<!-- google analytics -->

</body>

</html>


nn.js


var network= {
"profile":[

{
"id": "U78424D59",
"name":"Laurence Daheron",
"job":"",
"affiliation":"",
"www":"",
"img":"",
"tags":[],
"pos":{"x":0,"y":0},
"goal":{"x":0,"y":0},
"g":null
}
,
{
"id": "UAD17B888",
"name":"Duncan Hull",
"job":"Researcher",
"affiliation":"University of Manchester, UK",
"www":"http://www.cs.man.ac.uk/~hulld/",
"img":"http://network.nature.com/assets/user/000/001/271/large.png",
"tags":["bioinformatics"],
"pos":{"x":0,"y":0},
"goal":{"x":0,"y":0},
"g":null
}
(...)


],
"group":[

{
"uri": "G478D9F2D",
"name":"Physics Education",
"members":["U3CFE0669"] }
,
(...)

],
"link":[

["U78424D59","U363EDF9C"],
["U400B1F54","UE19877E8"],
(...)
]
};


nn.rdf

<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:nn="http://network.nature.com/" xmlns:dc="http://purl.org/dc/elements/1.1/">
<foaf:Person rdf:about="http://network.nature.com/profile/U78424D59">
<foaf:name>Laurence Daheron</foaf:name>
</foaf:Person>
<foaf:Person rdf:about="http://network.nature.com/profile/UAD17B888">
<foaf:name>Duncan Hull</foaf:name>
<nn:job>Researcher</nn:job>
<nn:affiliation>University of Manchester, UK</nn:affiliation>
<foaf:weblog rdf:resource="http://www.cs.man.ac.uk/~hulld/"/>
<foaf:img rdf:resource="http://network.nature.com/assets/user/000/001/271/large.png"/>
<dc:subject>bioinformatics</dc:subject>
</foaf:Person>


<foaf:Person rdf:about="http://network.nature.com/profile/U337FD68F">
<foaf:name>Peter Kirkpatrick</foaf:name>
<nn:job>Chief Editor</nn:job>
<nn:affiliation>Nature Reviews Drug Discovery</nn:affiliation>
<foaf:weblog rdf:resource="http://www.nature.com/nrd"/>
<dc:subject>biotechnology</dc:subject>
<dc:subject>drug discovery</dc:subject>
</foaf:Person>
(...)

<foaf:Group rdf:about="http://network.nature.com/group/G478D9F2D">
<foaf:name>Physics Education</foaf:name>
<foaf:member rdf:resource="http://network.nature.com/profile/U3CFE0669"/>
</foaf:Group>

<foaf:Group rdf:about="http://network.nature.com/group/SciDev">
<foaf:name>Science for Development</foaf:name>
<foaf:member rdf:resource="http://network.nature.com/profile/U9C60B47D"/>
<foaf:member rdf:resource="http://network.nature.com/profile/U78C3A2B2"/>
<foaf:member rdf:resource="http://network.nature.com/profile/U5F7D848C"/>
<foaf:member rdf:resource="http://network.nature.com/profile/UE8DA26E7"/>
</foaf:Group>

(...)
(...)
<nn:Connection rdf:nodeId="1">
<nn:contact rdf:resource="http://network.nature.com/profile/U78424D59"/>
<nn:contact rdf:resource="http://network.nature.com/profile/U363EDF9C"/>
</nn:Connection>
<nn:Connection rdf:nodeId="2">
<nn:contact rdf:resource="http://network.nature.com/profile/U400B1F54"/>
<nn:contact rdf:resource="http://network.nature.com/profile/UE19877E8"/>
</nn:Connection>
<nn:Connection rdf:nodeId="3">
<nn:contact rdf:resource="http://network.nature.com/profile/U400B1F54"/>
<nn:contact rdf:resource="http://network.nature.com/profile/U2929A0EA"/>
</nn:Connection>
(...)
</rdf:RDF>

Google Developer Day Paris 2007

My inscription to the google developer day Paris 2007 has been confirmed. The workshop will take place near the Bastille at Paris on May 31st. Here is the program (I asked to be part of all the topics named 'A').

Slot 1 – 14h30

Choice A – Introduction to Google API(100 pers.)
Choice B – Google Data API – Google Calendar and Blogger (100 pers.)



Slot 2 – 15h30
Choice A – Google Gadgets (85 pers.)
Choice B – Google Earth KML - KML for Earth et Maps, dynamic KML , referencing KML (85 pers.)
Choice C – Workshop Google Maps API - tools for politics (Desirsdavenir.com) (30 pers.)

Slot 3 – 17h00

Choice A– Google Maps API - Introduction (85 pers.)
Choice B – Google Apps & Google Search Appliance API (85 pers.)
Choice C – Workshop OpenSource & Google Maps API - (Project Coworking) (30 pers.)

Slot 4 – 18h00

Choice A – Google Web Toolkit : easy, quick & beautiful (85 pers.)
Choice B – AdWords API (85 pers.)
Choice C – Workshop OpenSource & Google Maps API - Projet CrowdUp (30 pers.)


Pierre

14 May 2007

UniProt RDF via HTTP

Eric Jain has descibed some features about the Unitprot database in RDF in the public-semweb-lifesci@w3.org mailing list.

Getting a single database entry:

http://beta.uniprot.org/uniprot/P00750.rdf
http://beta.uniprot.org/taxonomy/9606.rdf
http://beta.uniprot.org/pathways/9.149.94.241.rdf

http://beta.uniprot.org/uniprot/P12345.rdf
http://beta.uniprot.org/uniprot/P12345.xml
http://beta.uniprot.org/uniprot/P12345.fasta


Get all reviewed, human entries (16'267):

http://beta.uniprot.org/uniprot/?query=organism:9606+reviewed:yes&format=rdf

Same as above, but only first 1'000 entries, and gzipped:

http://beta.uniprot.org/uniprot/?query=organism:9606+reviewed:yes&format=rdf&offset=0&limit=1000&compress=yes

For other queries, just play with the Web interface

From a LSID identifier

http://beta.uniprot.org/?query=urn:lsid:uniprot.org:uniprot:P12345

http://beta.uniprot.org

Some links to the free encyclopedia Wikipedia were recently added in the web resource section. Proteins with a link to Wikipedia are mainly of medical or pharmaceutical interest. Wikipedia articles may describe the discovery of the protein and its use in medicine.


Examples:
Erythropoeitin (P01588)
Renin (P00797)
Insulin (P01308)
Ghrelin (Q9UBU3)