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)

10 May 2007

Structured Abstracts

There was a discussion about creating semantic/structured abstracts of papers in Nautilus , in Neil's blog and I also suggested it before. We can fantasize about this but for this and other things (tagging, unique id for authors, ...) we are still dependent of the NCBI. A central repository of those structured abstract could be created but I fear it would be only filled by a only few people. Moreover using text mining on pubmed can give some good results: see http://www.ihop-net.org/UniPub/iHOP/ (There may be other refs but I like this one).

Pierre

SciFoo 2007


I've just received an invitation to attend SciFoo 2007. Whaaaaa ! Thank you Timo ! I'm deeply honored and I've got a swollen head ! I was not able to come last year (I would have dreamed to meet Scott McLoud) and I still don't know if I can afford to go there for just three days but I should take my decision in the very next days. I’m also a little intimidated and I fear I'll be an unintelligible shy unsociable fake french idiot among all those famous smart persons.

Pierre

PS: Anybody knows what came out from SciFoo last year ?

JavaFX

(Via Paul's comment)

Sun introduced JavaFX at JavaOne. JAVAFX is a new scripting language based on java and it is said to be a flash/flex killer (I tested it, it still needs a java runtime environement and a basic knowledge of Swing is still needed, so I wonder how it could be compared with the light flash plugin ?)



see:
https://openjfx.dev.java.net/
https://openjfx.dev.java.net/JavaFX_Programming_Language.html
http://www.sun.com/software/javafx/


Pierre

SharedCopy: A collaborative tool for annotating web pages

Via TechCrunch: SharedCopy is a collaborative tool for annotating web pages. It takes a snapshot of the current page and uses it for annotations: then the visitors will sees the original page. I've tested it on a paper in pubmedcentral:


Pierre

08 May 2007

Hello World ! My first FLEX2 Application.

Adobe Flex 2 software is a rich Internet application framework based on Adobe Flash that will enable you to productively create beautiful, scalable applications that can reach virtually anyone on any platform.

The SDK was downloaded and extracted from : http://download.macromedia.com/pub/flex/sdk/flex_sdk_2.zip.

File:first.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
horizontalAlign="center" verticalAlign="center">
<mx:Button id="myButton" label="Hello Bioinformatics World !" />
</mx:Application>


The file was compiled to flash using the mxmlc command (a java application):
>FLEX/SDK/bin/mxmlc --strict=true --file-specs first.mxml
Loading configuration file FLEX/SDK/frameworks/flex-config.xml
FLEX/test/first.swf (125402 bytes)
> ls
first.mxml first.swf


I then opened first.swf in firefox and...
My First FLEX2 app

Whaaaa ! It worked without any problem !!

I'M THE KING OF THE WORLD !!


This looks exciting ! I need a good tutorial ! I need a good tutorial ! I need ....


Pierre :-)

06 May 2007

04 May 2007

Hello World in MQL/ Freebase.

OK, here are my very first tests in freebase.
The MQL query language is used to send the query to the server. It is based on the JSON format.

The following MQL query asks for the date/place of birth, the gender, for all the biologists in freebase.


{
"query":[{
"/people/person/date_of_birth":null,
"/people/person/gender":null,
"/people/person/place_of_birth":null,
"/people/person/profession":"biologist",
"name":null
}]
}


This query can be copied in the freebase query editor (http://www.freebase.com/view/queryeditor/) or can be send via http (see below my example in java).

Here is the result formated in JSON as it appears in the editor:


{
"q1": {
"status": "/mql/status/ok",
"result": [
{
"/people/person/date_of_birth": "1809-12-02",
"/people/person/profession": "Biologist",
"/people/person/gender": "Male",
"name": "Charles Darwin",
"/people/person/place_of_birth": "Shrewsbury"
},
{
"/people/person/date_of_birth": "1859",
"/people/person/profession": "Biologist",
"/people/person/gender": "Male",
"name": "Jacques Loeb",
"/people/person/place_of_birth": null
}
]
},
"status": "200 OK"
}


Only two records ! :-) because as far as I could see, Freebase was automatically generated from wikipedia (name, description ...) whereas most fields (gender, date of birth etc...) remain empty and are waiting for the users to be filled.

Iv' also tried to send this query via JAVA.


import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;





public class Test01 {
static final String BASE_URL="http://www.freebase.com";
static final String MQLREADURL=BASE_URL+"/api/service/mqlread";


void query(String json) throws IOException
{
String envelope = "{\"qname\":{\"query\":" +json+ "}}";
String urlStr =MQLREADURL+"?queries="+URLEncoder.encode(envelope, "UTF-8");

// Now place the query in JSON envelope objects, and URL encode the envelopes
URL url= new URL(urlStr);
URLConnection con=url.openConnection();
//set the cookie
con.setRequestProperty("Cookie","metaweb-user="+###YOUR_COOKIE_VALUE###);
con.connect();
InputStream in=con.getInputStream();
int c;
//echo the result to stdout
while((c=in.read())!=-1) System.out.write(c);
in.close();
}


public static void main(String[] args)
{
try {
Test01 t= new Test01();
t.query("[{ \"/people/person/date_of_birth\":null, \"/people/person/gender\":null, \"/people/person/place_of_birth\":null, \"/people/person/profession\":\"biologist\", \"name\":null }] ");

} catch (Exception e) {
e.printStackTrace();
}
}

}


This source uses a URLConnection object to send the query. You may notice that the value of a cookie called metaweb-user must be provided. This cookie identifies your account on freebase and its value can be found in the "preferences panel: Privacy" in firefox.

Pierre.

(Trying to use) The NCBI ASN.1 library

Motivation: I was looking for a way to store and to read my linkage data using a binary format, (then I could get a faster and a smaller size).

I had a glance to the NCBI C toolbox which uses ASN.1 as its main format to encode and to structure the data just like XML.

About ASN1: ASN.1 is a standard that describes data structures for representing, encoding, transmitting, and decoding data. It provides a set of formal rules for describing the structure of objects that are independent of machine-specific encoding techniques and is a precise, formal notation that removes ambiguities. Its usage can be compared to the more recent XML Schema (see also my previous post about JAXB).

The NCBI ASN1 C library is descibed here: http://www.ncbi.nlm.nih.gov/IEB/ToolBox/SDKDOCS/ASNLIB.HTML

Although I still have a problem in the last part, this post can be considered as my first experience with the ASN.1 library.

I started my test by defining a small ASN.1 module to store some PCR primers and their hits on the genome


PCRMod DEFINITIONS ::=
BEGIN
Orientation ::= ENUMERATED
{
forward(0),
reverse(1)
}

Hit ::= SEQUENCE
{
chromosome VisibleString, -- chromosome
start INTEGER, -- starting position in chromosome 5' + strand
orient Orientation -- orientation
}

Primer ::= SEQUENCE {
name VisibleString, -- name
tm REAL OPTIONAL, -- melting temperature
sequence VisibleString, -- sequence
hits SET OF Hit OPTIONAL -- hits
}

PrimerInput ::=SEQUENCE OF Primer

END


This schema 'primer.asn' was digested by the asntool


asntool -Z T -w 128 -m primer.asn -G T -B primer -K primerasn
asntool -Z T -w 128 -m primer.asn-o primerasn.h


here asntool will read the 'primer.asn' and will generate three source files:

primerasn.h: is a C header containing all states that will be used the parse the ASN1 files.
/***********************************************************************
*
**
* Automatic header module from ASNTOOL
*
************************************************************************/

(...)

static char * asnfilename = "primerasn.h";
static AsnValxNode avnx[2] = {
{20,"forward" ,0,0.0,&avnx[1] } ,
{20,"reverse" ,1,0.0,NULL } };

static AsnType atx[20] = {
{401, "Orientation" ,1,0,0,0,0,0,0,0,NULL,&atx[1],&avnx[0],0,&atx[2]} ,
{310, "ENUMERATED" ,0,10,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
{402, "Hit" ,1,0,0,0,0,0,0,0,NULL,&atx[8],&atx[3],0,&atx[9]} ,
{0, "chromosome" ,128,0,0,0,0,0,0,0,NULL,&atx[4],NULL,0,&atx[5]} ,
{323, "VisibleString" ,0,26,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
{0, "start" ,128,1,0,0,0,0,0,0,NULL,&atx[6],NULL,0,&atx[7]} ,
{302, "INTEGER" ,0,2,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
{0, "orient" ,128,2,0,0,0,0,0,0,NULL,&atx[0],NULL,0,NULL} ,
{311, "SEQUENCE" ,0,16,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
{403, "Primer" ,1,0,0,0,0,0,0,0,NULL,&atx[8],&atx[10],0,&atx[17]} ,
{0, "name" ,128,0,0,0,0,0,0,0,NULL,&atx[4],NULL,0,&atx[11]} ,
{0, "tm" ,128,1,0,1,0,0,0,0,NULL,&atx[12],NULL,0,&atx[13]} ,
{309, "REAL" ,0,9,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
{0, "sequence" ,128,2,0,0,0,0,0,0,NULL,&atx[4],NULL,0,&atx[14]} ,
{0, "hits" ,128,3,0,1,0,0,0,0,NULL,&atx[16],&atx[15],0,NULL} ,
{0, NULL,1,-1,0,0,0,0,0,0,NULL,&atx[2],NULL,0,NULL} ,
{314, "SET OF" ,0,17,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} ,
{404, "PrimerInput" ,1,0,0,0,0,0,0,0,NULL,&atx[19],&atx[18],0,NULL} ,
{0, NULL,1,-1,0,0,0,0,0,0,NULL,&atx[9],NULL,0,NULL} ,
{312, "SEQUENCE OF" ,0,16,0,0,0,0,0,0,NULL,NULL,NULL,0,NULL} };

static AsnModule ampx[1] = {
{ "PCRMod" , "primerasn.h",&atx[0],NULL,NULL,0,0} };

static AsnValxNodePtr avn = avnx;
static AsnTypePtr at = atx;
static AsnModulePtr amp = ampx;



/**************************************************
*
* Defines for Module PCRMod
*
**************************************************/

#define ORIENTATION &at[0]

#define HIT &at[2]
#define HIT_chromosome &at[3]
#define HIT_start &at[5]
#define HIT_orient &at[7]

#define PRIMER &at[9]
#define PRIMER_name &at[10]
#define PRIMER_tm &at[11]
#define PRIMER_sequence &at[13]
#define PRIMER_hits &at[14]
#define PRIMER_hits_E &at[15]

#define PRIMERINPUT &at[17]
#define PRIMERINPUT_E &at[18]




primer.h: contains the C headers used to parse the structure declared in the ASN1 schema. There is a method to allocate/free/read and write each structure.
#
(...)
/**************************************************
*
* Generated objects for Module PCRMod
*
**************************************************/

NLM_EXTERN Boolean LIBCALL
primerAsnLoad PROTO((void));
/* following #defines are for enumerated type, not used by object loaders */
#define Orientation_forward 0
#define Orientation_reverse 1



/**************************************************
* Hit
**************************************************/
typedef struct struct_Hit {
struct struct_Hit PNTR next;
Uint4 OBbits__;
CharPtr chromosome;
Int4 start;
Uint2 orient;
} Hit, PNTR HitPtr;


NLM_EXTERN HitPtr LIBCALL HitFree PROTO ((HitPtr ));
NLM_EXTERN HitPtr LIBCALL HitNew PROTO (( void ));
NLM_EXTERN HitPtr LIBCALL HitAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
NLM_EXTERN Boolean LIBCALL HitAsnWrite PROTO (( HitPtr , AsnIoPtr, AsnTypePtr));



/**************************************************
* Primer
**************************************************/
typedef struct struct_Primer {
struct struct_Primer PNTR next;
Uint4 OBbits__;
CharPtr name;
#define OB__Primer_tm 0

FloatHi tm;
CharPtr sequence;
struct struct_Hit PNTR hits;
} Primer, PNTR PrimerPtr;


NLM_EXTERN PrimerPtr LIBCALL PrimerFree PROTO ((PrimerPtr ));
NLM_EXTERN PrimerPtr LIBCALL PrimerNew PROTO (( void ));
NLM_EXTERN PrimerPtr LIBCALL PrimerAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
NLM_EXTERN Boolean LIBCALL PrimerAsnWrite PROTO (( PrimerPtr , AsnIoPtr, AsnTypePtr));



/**************************************************
* PrimerInput
**************************************************/
typedef struct struct_Primer PrimerInput;
typedef struct struct_Primer PNTR PrimerInputPtr;
#define PrimerInputNew() PrimerNew()



NLM_EXTERN PrimerInputPtr LIBCALL PrimerInputFree PROTO ((PrimerInputPtr ));
NLM_EXTERN PrimerInputPtr LIBCALL PrimerInputNew PROTO (( void ));
NLM_EXTERN PrimerInputPtr LIBCALL PrimerInputAsnRead PROTO (( AsnIoPtr, AsnTypePtr));
NLM_EXTERN Boolean LIBCALL PrimerInputAsnWrite PROTO (( PrimerInputPtr , AsnIoPtr, AsnTypePtr));
(...)


and primer.c the C implementation of those methods.

(...)


OK, here comes the problem: I wrote a simple ASN1 input
PrimerInput::={
{
name "Primer0",
sequence "ATAGCTACTGATGCATGCATCG"
}
}


and I wanted to read each primer. Here is my source:
#include <cerrno>
#include <fstream>
#include <iostream>
#include <string>
#include <stdexcept>
#include <asn.h>
#include <cassert>

/** include the files generated by the ASN1 tool */
#include <primer.h>
#include <primerasn.h>

int main(int argc, char** argv)
{
int optind=1;

/* init my specification */
if(!primerAsnLoad())
{
fprintf(stderr,"#%s: cannot load ASN1 specification \"%s\".\n" ,
argv[0],asnfilename );
return (EXIT_FAILURE);
}

if(optind+1!=argc)
{
fprintf(stderr,"bad input : usage %s ASN1 file\n",argv[0]);
return(EXIT_FAILURE);
}

/** open the input file */
AsnIoPtr in = AsnIoOpen(argv[1],"r");
if(in==NULL)
{
fprintf(stderr,"Cannot Read %s\n",argv[1]);
return(EXIT_FAILURE);
}


/** init the state of the parser */
AsnTypePtr asn_type_ptr=PRIMERINPUT;
PrimerPtr primer= NULL;

/** while we can read a primer... */
while ((asn_type_ptr = AsnReadId(in, amp, asn_type_ptr)) != NULL)
{
if(asn_type_ptr==PRIMERINPUT_E)
{
primer= PrimerAsnRead(in,asn_type_ptr);
if(primer!=NULL)
{
fprintf(stderr,"sequence: %s\n",primer->sequence);
PrimerFree(primer);
}
}
else
{
AsnReadVal(in, asn_type_ptr,NULL);
}
}

AsnIoClose(in);
return(0);
}


The problem: my input file is processed silently but the output shows two primers insted of one and the sequence is said to be NULL.

sequence: (null)
sequence: (null)


I'm blocked here :-)


Pierre