31 October 2006

JAVA custom Annotation & Concurrent Versions System

I manage my sources using CVS (Concurrent Versions System). When a user reported a bug in one of my java program, I faced the problem to get the version of the java class where the Exception was throwed..... I don't know if this was described but here is my solution using a custom java annotation. CVS can use a mechanism known as keyword substitution (or keyword expansion) to help identifying the files. Embedded strings of the form $keyword$ and $keyword:…$ in a file are replaced with strings of the form $keyword:value$ whenever you obtain a new revision of the file. Here I used Date,Source and Revision.

First I defined a new custom Annotation called @RCS returning the author, a date and a revision.

import java.lang.annotation.*;
/**
* describe a Revision Control System
* @author pierre
*
*/
@Retention(RetentionPolicy.RUNTIME) /* The annotation should be available for reflection at runtime.*/
@Target(ElementType.TYPE) /* place in : class, interface, enum */
public @interface RCS {
/** author of this source */
String author() default '[undefined]';
/** revision number of this source */
String revision() default '[undefined]';
/** date of revision of this source */
String date() default '[undefined]';
/** file name for this source */
String source() default '[undefined]';
}


and here are two files used for test. Both classes contains a @RCS annotation which can be find at runtime. Test2 jsut throws an Exception. Test1 catch this exception and display the stack trace. for each StackTraceElement it tries to find a @RCS annotation.


import java.lang.annotation.*;
@RCS( author='$Author: $',
date='$Date: $',
source='$Source: $',
revision='$Revision: $'
)

public class Test
{

Test()
{
Test2 t=new Test2();
t.doSomething();
}



public static void main(String args[])
{
try
{
Test t= new Test();
}
catch(Exception err)
{

System.err.println(err.getLocalizedMessage());
for(StackTraceElement e: err.getStackTrace())
{
System.err.println('Class :\t\t\t'+e. getClassName());
System.err.println('File :\t\t\t'+e. getFileName());
System.err.println('Line :\t\t\t'+e. getLineNumber());

if(e.getClassName()!=null)
{
try {
Class c= Class.forName( e.getClassName());
RCS rcsInfo=(RCS)c.getAnnotation(RCS.class);
System.err.println('Revision:\t\t'+(rcsInfo==null?'N/A':rcsInfo.revision()));
System.err.println('Date:\t\t\t'+(rcsInfo==null?'N/A':rcsInfo.date()));
System.err.println('Author:\t\t\t'+(rcsInfo==null?'N/A':rcsInfo.author()));
}
catch (Exception err2)
{
}
}
System.err.println();
}
}

}
}



@RCS(   author='$Author:  $',
date='$Date: $',
source='$Source: $',
revision='$Revision: $'
)

public class Test2
{
Test2()
{
}
void doSomething()
{
throw new RuntimeException('Test');
}

}


when the files where committed the CVS fields were substituted by their correct values. Here is the stack trace as it was printed:


pierre@linux:~/tmp/src> cvs commit
(...)
pierre@linux:~/tmp/src> javac Test.java
pierre@linux:~/tmp/src> java Test
Test
Class : Test2
File : Test2.java
Line : 13
Revision: $Revision: 1.2 $
Date: $Date: 2006/10/31 18:10:44 $
Author: $Author: pierre $


Class : Test
File : Test.java
Line : 15
Revision: $Revision: 1.5 $
Date: $Date: 2006/10/31 18:54:08 $
Author: $Author: pierre $


Class : Test
File : Test.java
Line : 24
Revision: $Revision: 1.5 $
Date: $Date: 2006/10/31 18:54:08 $
Author: $Author: pierre $



That's it.
Pierre

Pubmed "Abstract Plus" and Pubmed2connotea

I didn't mention it before, but I've upgraded the greasemonkey script pubmed2connotea for the new "Abstract Plus" format in pubmed. Pubmed2connotea/Pubmed2CiteULike is a Greasemonkey user script which alters the content web
page when browsing your bibliography on NCBI pubmed by inserting
a hyperlink. This new link adds a new bookmark into connotea with the current selected paper.

Update the latest version at http://www.urbigene.com/pubmed2connotea/.



Pierre

Zotero

zotero is a free Firefox extension, easy-to-use research tool that helps you gather and organize resources (whether bibliography or the full text of articles), and then lets you to annotate, organize, and share the results of your research. It includes the best parts of older reference manager software (like EndNote)—the ability to store full reference information in author, title, and publication fields and to export that as formatted references—and the best parts of modern software such as del.icio.us , like the ability to sort, tag, and search in advanced ways.



In zotero, data are stored using the sqlite, so using an external sqlite engine, you can query or update the database without firefox/mozilla:

pierre@linux:~/> echo ".tables" |./sqlite3-3.3.8.bin -separator '   ' -header ~/.mozilla/firefox/xxxx.default/zotero/zotero.sqlite

charsets itemAttachments tags
collectionItems itemCreators transactionLog
collections itemData transactionSets
creatorTypes itemNotes transactions
creators itemSeeAlso translators
csl itemTags userFieldMask
fieldFormats itemTypeCreatorTypes userFields
fields itemTypeFields userItemTypeFields
fileTypeMimeTypes itemTypes userItemTypeMask
fileTypes items userItemTypes
fulltextItems savedSearchConditions version
fulltextWords savedSearches


pierre@linux:~/> echo "select * from items order by dateAdded;" |./sqlite3-3.3.8.bin-separator ' ' -header ~/.mozilla/firefox/xxxx.default/zotero/zotero.sqlite

itemID itemTypeID title dateAdded dateModified
8423 4 Haplotypes in the gene encoding protein kinase c-beta (PRKCB1) on chromosome 16 are associated with autism. 2006-10-30 18:47:16 2006-10-30 18:47:56
15625 1 2006-10-30 18:48:11 2006-10-31 10:50:53


About sqlite: There is a video about this engine on google-video.


23 October 2006

Things about Bioinformatics #1

Hum, too much work , I've not enough time to write some original post on this blog. So, as Deepak Singh did on business|bytes|genes|molecules, I'm also starting a series of post about thing I noticed:

dbSNP: From dbSNP: Users may now query genotypes for 1 or more snps by rs#, chromosome location, or gene Id. SNP properties and populations are specified prior to retrieval. Output includes HTML, XML, Text and HaploView format by population.
http://www.ncbi.nlm.nih.gov/projects/SNP/snp_gf.cgi

Calendar: I've started to use google's calendar and I created a shared one about bioinformatics (mostly for test but I'll try to keep it up to date). Here is its address in XML and in iCal format. (See also: upcoming.org)

Connotea: Ben Lund has created a new (beta) tool for connotea called Notea: Notea is a Firefox Extension for storing and organizing local copies of online works. It optionally integrates with Connotea to allow easy sharing of bookmarks for your locally stored works.

Del.icio.us: from time to time, I synchronize my tagged bookmarks from connotea to del.icio.us (using xslt and curl) . Del.icio.us has a few functionalities that are missing to connotea: discovering sites using the network, suggesting links, tag bundles....

Comics: want to know more about North Korea ? Do read this comics : "Pyongyang: A Journey to North Korea."



Comics: 300, a film based on Frank Miller's graphic novel 300 about the the battle of thermopylae will be in theaters in 2007. The comparison between the book and the movie is astonishing !

The book:


The movie:


Pierre

05 October 2006

A Google Gadget for Bioinformatics.

As Pedro said on his blog: Google announced that their widgets (or gadgets) can now be used on third party webpages.. I've written ([here])a google gadget searching for pubmed or genbank using the NCBI EUtilies. Enjoy !





Add to Google



Pierre

Updated 2010-08-12: source code

<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs
title="Search NCBI/__UP_db__"
directory_title="Search NCBI/__UP_db__"
description="Search Pubmed/Genbank at the National Center for Biotechnology Information (NCBI)"
author="Pierre Lindenbaum PhD"
author_email="plindenbaum+gadget4ncbi@yahoo.fr"
title_url="http://www.urbigene.com/googlegadget/index.html#gadget4ncbi"
author_affiliation="Integragen"
author_location="Evry,France"
height="200"
width="320"
scrolling="true"
singleton="true"
screenshot="http://www.urbigene.com/googlegadget/ncbi_screenshot.png"
thumbnail="http://www.urbigene.com/googlegadget/ncbi_thumbnail.png"
author_photo="http://www.urbigene.com/googlegadget/plindenbaum.png"
author_link="http://plindenbaum.blogspot.com"
author_aboutme="Bioinformatician at Integragen"
author_quote="A child of five would understand this. Send someone to fetch a child of five. "
>
<Locale lang="en"/>
<Locale lang="ja"/>
<Locale lang="fr"/>
<Locale lang="de"/>
<Locale lang="zn-cn"/>
<Locale lang="zh-tw"/>
</ModulePrefs>
<UserPref name="term"
display_name="Your Query"
datatype="string"
required="true"
default_value="Rotavirus"
/>
<UserPref name="db"
display_name="Database"
datatype="enum"
required="true"
default_value="pubmed">
<EnumValue value="pubmed" display_value="Pubmed"/>
<EnumValue value="nucleotide" display_value="Nucleotide"/>
<EnumValue value="protein" display_value="Protein"/>
</UserPref>
<UserPref name="retmax"
display_name="Number of items retrieved"
datatype="enum"
required="true"
default_value="10">
<EnumValue value="1" display_value="1"/>
<EnumValue value="2" display_value="2"/>
<EnumValue value="10" display_value="10"/>
<EnumValue value="15" display_value="15"/>
<EnumValue value="20" display_value="20"/>
<EnumValue value="25" display_value="25"/>
<EnumValue value="50" display_value="50"/>
<EnumValue value="100" display_value="100"/>
</UserPref>
<Content type="html"><![CDATA[
<style>
#content__MODULE_ID__ {
font-size: 9pt;
margin: 5px;
background-color: #FFFFBF;
}
dt {
font-size: 9pt;
}
dd {
font-size: 7pt;
}

</style>
<div id="content__MODULE_ID__"></div>
<script type="text/javascript">

var prefs__MODULE_ID__ = new _IG_Prefs(__MODULE_ID__);

function dom1__MODULE_ID__(node,tag)
{
if(node==null || tag==null) return null;
var n=node.firstChild;
while(n!=null)
{
if(n.nodeName==tag) return n;
n=n.nextSibling;
}
return null;
}

function dom2__MODULE_ID__(node)
{
if(node==null) return "undefined";
var c= node.firstChild;
if(c==null) return "undefined";
return c.nodeValue;
}

function pubmed__MODULE_ID__(response)
{
var nodes = response.getElementsByTagName("PubmedArticle");
var html="<div><dl>";
for (var i = 0; i < nodes.length ; i++)
{
var MedlineCitation= dom1__MODULE_ID__(nodes.item(i),"MedlineCitation");
var PMID= dom1__MODULE_ID__(MedlineCitation,"PMID");
var Article = dom1__MODULE_ID__(MedlineCitation,"Article");
var ArticleTitle = dom1__MODULE_ID__(Article,"ArticleTitle");
var Title = dom1__MODULE_ID__(dom1__MODULE_ID__(MedlineCitation,"MedlineJournalInfo"),"MedlineTA");
var AuthorList = dom1__MODULE_ID__(Article,"AuthorList");
var Author = dom1__MODULE_ID__(AuthorList,"Author");
var LastName = dom1__MODULE_ID__(Author,"LastName");

html+='<dt><a title=\"show this Article\" href=\"http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=pubmed&amp;cmd=Retrieve&amp;dopt=AbstractPlus&amp;list_uids='+dom2__MODULE_ID__(PMID)+
'\" target=\"pubmed'+dom2__MODULE_ID__(PMID)+
'\">'+dom2__MODULE_ID__(ArticleTitle)+'</a></dt>';
html+='<dd><i>'+dom2__MODULE_ID__(Title)+'</i>. <u>'+dom2__MODULE_ID__(LastName)+'</u> &amp; al.</dd>';
}

html+="</dl></div>";
_gel("content__MODULE_ID__").innerHTML = html;

}

function sequence__MODULE_ID__(response)
{
var nodes = response.getElementsByTagName("TSeq");
var html="<div><dl>";
for (var i = 0; i < nodes.length ; i++)
{
var c=nodes.item(i);
var TSeq_seqtype = dom1__MODULE_ID__(c,"TSeq_seqtype");
var TSeq_gi = dom1__MODULE_ID__(c,"TSeq_gi");
var TSeq_accver = dom1__MODULE_ID__(c,"TSeq_accver");
var TSeq_orgname = dom1__MODULE_ID__(c,"TSeq_orgname");
var TSeq_defline = dom1__MODULE_ID__(c,"TSeq_defline");
var TSeq_length = dom1__MODULE_ID__(c,"TSeq_length");

html+='<dt><a title=\"Show this Sequence\" href=\"http://www.ncbi.nlm.nih.gov/entrez/viewer.fcgi?db='+
TSeq_seqtype.getAttribute("value")+
'&amp;val='+dom2__MODULE_ID__(TSeq_gi)+
'\" target=\"seq'+dom2__MODULE_ID__(TSeq_gi)+
'\">'+dom2__MODULE_ID__(TSeq_defline)+'</a></dt>'+
'<dd><i>'+
dom2__MODULE_ID__(TSeq_accver)+
'</i>. <i>'+dom2__MODULE_ID__(TSeq_orgname)+'</i>. (length:'+dom2__MODULE_ID__(TSeq_length)+')</dd>';
}

html+="</dl></div>";


_gel("content__MODULE_ID__").innerHTML = html;
}


function dofetch__MODULE_ID__(response)
{
if (response == null ||
typeof(response) != "object" ||
response.firstChild == null)
{
_gel("content__MODULE_ID__").innerHTML = "<i>Invalid data for efetch</i>";
return;
}
if(prefs__MODULE_ID__.getString("db")=="pubmed")
{
pubmed__MODULE_ID__(response);
}
else
{
sequence__MODULE_ID__(response);
}
}

function doesearch__MODULE_ID__(response)
{

if (response == null ||
typeof(response) != "object" ||
response.firstChild == null)
{
_gel("content__MODULE_ID__").innerHTML = "<i>Invalid data for search</i>";
return;
}
var nodes = response.getElementsByTagName("QueryKey");
if(nodes==null || nodes.length!=1)
{
_gel("content__MODULE_ID__").innerHTML = "<i>Error with QueryKey</i>";
return;
}
var QueryKey=nodes.item(0).firstChild.nodeValue;
nodes = response.getElementsByTagName("WebEnv");
if(nodes==null || nodes.length!=1)
{
_gel("content__MODULE_ID__").innerHTML = "<i>Error with WebEnv</i>";
return;
}
var WebEnv=nodes.item(0).firstChild.nodeValue;
var url= "http://www.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db="+
prefs__MODULE_ID__.getString("db")+
"&WebEnv="+escape(WebEnv)+
"&query_key="+escape(QueryKey)+
"&tool=gadget4ncbi"+
"&retmode=xml"+
"&usehistory=y"+
"&retmax="+prefs__MODULE_ID__.getString("retmax");

if(prefs__MODULE_ID__.getString("db")!="pubmed")
{
url+="&rettype=fasta";
}

_IG_FetchXmlContent(url,dofetch__MODULE_ID__);
}

function dogadget__MODULE_ID__()
{
var url= "http://www.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db="+
prefs__MODULE_ID__.getString("db")+
"&term="+escape(prefs__MODULE_ID__.getString("term"))+
"&tool=gadget4ncbi"+
"&retmode=xml"+
"&usehistory=y"+
"&retmax="+prefs__MODULE_ID__.getString("retmax");
_IG_FetchXmlContent(url,doesearch__MODULE_ID__);
}

_IG_RegisterOnloadHandler(dogadget__MODULE_ID__);

</script>
]]></Content>
</Module>