[Biojava-dev] Protein Alignment Exception
Chris Friedline
cfriedline at vcu.edu
Tue Dec 7 18:42:39 UTC 2010
John,
1.7.1 is the latest stable release, but there is a dev branch of 1.7.1 that
is different in some cases than the distributed version on the website, but
is not biojava3. BioJava3 is the next release to the BioJava libraries due
out (hopefully) soon and is currently building (Maven) at beta2.
There is definitely more functionality in the alignment pair that is
returned in BioJava3 from the pairwise alignment, including a way to get
what you closer to want below (e.g., getNumIdenticals()/getLength()),
traverse in both sequence and alignment space, and much more. Percent
similarity can get tricky with protein alignments, though. There's also
nice string output, in several formats (ALN, Clustal, etc).
Chris
On Tue, Dec 7, 2010 at 1:16 PM, John Hawkins <
john.hawkins at biotec.tu-dresden.de> wrote:
> Thanks Chris,
>
> I am a little confused, when I go to the download page for BioJava it
> appeared that 1.7.1 is still the latest.
> How stable are the BioJava3 libraries ?
>
> I agree that my SubstitutionMatrix code is ugly, but it was my quick hack
> to get things going.
>
>
> In the meantime I managed to solve my own problem, albeit in an inelegant
> fashion.
>
> The conflict was not between the alphabets of the two sequences, it was
> between the alphabets in
> the sequence and the one that was used to instantiate the
> SubstitutionMatrix.
>
> In essence I abandoned the idea of instantiating the Alphabet using
> AlphabetManager.alphabetForName.
> Instead I created the sequence objects first and took the alphabet from the
> first sequence object.
>
> The new code is below.
>
> Included in this code is another quick hack to calculate percent sequence
> identities from the alignments.
> I couldn't find this function built into the existing codebase, which
> seemed a little strange, is it something I
> overlooked ?
>
>
> ---------------------------------------------------------------
>
> package utilities;
>
> import org.biojava.bio.alignment.NeedlemanWunsch;
> import org.biojava.bio.alignment.SequenceAlignment;
> import org.biojava.bio.alignment.SmithWaterman;
> import org.biojava.bio.alignment.SubstitutionMatrix;
> import org.biojava.bio.seq.ProteinTools;
> import org.biojava.bio.seq.Sequence;
> import org.biojava.bio.symbol.AlphabetManager;
> import org.biojava.bio.symbol.FiniteAlphabet;
>
>
> public class PairWiseAlignment {
>
> private String seq1;
> private String seq2;
>
> private int score;
> private int score2;
> private String aln1;
> private String aln2;
> private double pid1;
> private double pid2;
>
> public PairWiseAlignment(String s1, String s2, int score, int score2,
> String aln1, String aln2) {
> super();
> this.seq1 = s1;
> this.seq2 = s2;
>
> this.score = score;
> this.score2 = score2;
> this.aln1 = aln1;
> this.aln2 = aln2;
> this.pid1 = getPID( s1, s2, aln1);
> this.pid2 = getPID( s1, s2, aln2);
>
> }
>
>
> /** This performs an alignment of two given sequences and
> * returns the result in an object.
> *
> * @param seq1 a query sequence
> * @param seq2 a target sequence
> */
> public static PairWiseAlignment alignProteins(String sequence1,
> String sequence2) {
>
> int score = 0;
> int score2 = 0;
> String aln1= "";
> String aln2= "";
> try {
>
> // LETS IGNORE THIS STEP AND TAKE THE ALPHABET OUT OF THE
> SEQUENCES
> //FiniteAlphabet alphabet = (FiniteAlphabet)
> AlphabetManager.alphabetForName("PROTEIN");
>
> Sequence query = ProteinTools.createProteinSequence(sequence1,
> "query");
> Sequence target = ProteinTools.createProteinSequence(sequence2,
> "target");
> FiniteAlphabet alphabet = (FiniteAlphabet) query.getAlphabet();
>
>
> SubstitutionMatrix matrix = new SubstitutionMatrix(alphabet,
> PairWiseAlignment.getSubstitutionMatrix(), "BLOSUM62");
> // Define the default costs for sequence manipulation for the
> global alignment.
> SequenceAlignment aligner = new NeedlemanWunsch(
> (short) 0, // match
> (short) 3, // replace
> (short) 2, // insert
> (short) 2, // delete
> (short) 1, // gapExtend
> matrix // SubstitutionMatrix
> );
>
> // Perform an alignment and save the results.
> score = aligner.pairwiseAlignment(
> query, // first sequence
> target // second one
> );
> aln1 = "Global alignment with Needleman-Wunsch:\n" +
> aligner.getAlignmentString();
>
> // Perform a local alginment from the sequences with
> Smith-Waterman.
> // Firstly, define the expenses (penalties) for every single
> operation.
> aligner = new SmithWaterman(
> (short) -1, // match
> (short) 3, // replace
> (short) 2, // insert
> (short) 2, // delete
> (short) 1, // gapExtend
> matrix // SubstitutionMatrix
> );
> // Perform the local alignment.
> score2 = aligner.pairwiseAlignment(query, target);
> //aligner.getAlignment(query, target).
> aln2 = "\nLocal alignment with SmithWaterman:\n" +
> aligner.getAlignmentString();
>
> } catch (Exception exc) {
> exc.printStackTrace();
> }
>
> return new PairWiseAlignment(sequence1, sequence2, score, score2,
> aln1, aln2);
>
> }
>
> public static String getSubstitutionMatrix() {
> //TODO: Load this as a resource
> String result = "# Matrix made by matblas from blosum62.iij
> \n" +
> "# * column uses minimum score\n" +
> "# BLOSUM Clustered Scoring Matrix in 1/2 Bit Units\n" +
> "# Blocks Database = /data/blocks_5.0/blocks.dat\n" +
> "# Cluster Percentage: >= 62\n" +
> "# Entropy = 0.6979, Expected = -0.5209\n" +
> " A R N D C Q E G H I L K M F P S T W Y V
> B Z X \n" +
> "A 4 -1 -2 -2 0 -1 -1 0 -2 -1 -1 -1 -1 -2 -1 1 0 -3 -2 0
> -2 -1 0 \n" +
> "R -1 5 0 -2 -3 1 0 -2 0 -3 -2 2 -1 -3 -2 -1 -1 -3 -2 -3
> -1 0 -1 \n" +
> "N -2 0 6 1 -3 0 0 0 1 -3 -3 0 -2 -3 -2 1 0 -4 -2 -3
> 3 0 -1 \n" +
> "D -2 -2 1 6 -3 0 2 -1 -1 -3 -4 -1 -3 -3 -1 0 -1 -4 -3 -3
> 4 1 -1 \n" +
> "C 0 -3 -3 -3 9 -3 -4 -3 -3 -1 -1 -3 -1 -2 -3 -1 -1 -2 -2 -1
> -3 -3 -2 \n" +
> "Q -1 1 0 0 -3 5 2 -2 0 -3 -2 1 0 -3 -1 0 -1 -2 -1 -2
> 0 3 -1 \n" +
> "E -1 0 0 2 -4 2 5 -2 0 -3 -3 1 -2 -3 -1 0 -1 -3 -2 -2
> 1 4 -1 \n" +
> "G 0 -2 0 -1 -3 -2 -2 6 -2 -4 -4 -2 -3 -3 -2 0 -2 -2 -3 -3
> -1 -2 -1 \n" +
> "H -2 0 1 -1 -3 0 0 -2 8 -3 -3 -1 -2 -1 -2 -1 -2 -2 2 -3
> 0 0 -1 \n" +
> "I -1 -3 -3 -3 -1 -3 -3 -4 -3 4 2 -3 1 0 -3 -2 -1 -3 -1 3
> -3 -3 -1 \n" +
> "L -1 -2 -3 -4 -1 -2 -3 -4 -3 2 4 -2 2 0 -3 -2 -1 -2 -1 1
> -4 -3 -1 \n" +
> "K -1 2 0 -1 -3 1 1 -2 -1 -3 -2 5 -1 -3 -1 0 -1 -3 -2 -2
> 0 1 -1 \n" +
> "M -1 -1 -2 -3 -1 0 -2 -3 -2 1 2 -1 5 0 -2 -1 -1 -1 -1 1
> -3 -1 -1 \n" +
> "F -2 -3 -3 -3 -2 -3 -3 -3 -1 0 0 -3 0 6 -4 -2 -2 1 3 -1
> -3 -3 -1 \n" +
> "P -1 -2 -2 -1 -3 -1 -1 -2 -2 -3 -3 -1 -2 -4 7 -1 -1 -4 -3 -2
> -2 -1 -2 \n" +
> "S 1 -1 1 0 -1 0 0 0 -1 -2 -2 0 -1 -2 -1 4 1 -3 -2 -2
> 0 0 0 \n" +
> "T 0 -1 0 -1 -1 -1 -1 -2 -2 -1 -1 -1 -1 -2 -1 1 5 -2 -2 0
> -1 -1 0 \n" +
> "W -3 -3 -4 -4 -2 -2 -3 -2 -2 -3 -2 -3 -1 1 -4 -3 -2 11 2 -3
> -4 -3 -2 \n" +
> "Y -2 -2 -2 -3 -2 -1 -2 -3 2 -1 -1 -2 -1 3 -3 -2 -2 2 7 -1
> -3 -2 -1 \n" +
> "V 0 -3 -3 -3 -1 -2 -2 -3 -3 3 1 -2 1 -1 -2 -2 0 -3 -1 4
> -3 -2 -1 \n" +
> "B -2 -1 3 4 -3 0 1 -1 0 -3 -4 0 -3 -3 -2 0 -1 -4 -3 -3
> 4 1 -1 \n" +
> "Z -1 0 0 1 -3 3 4 -2 0 -3 -3 1 -1 -3 -1 0 -1 -3 -2 -2
> 1 4 -1 \n" +
> "X 0 -1 -1 -1 -2 -1 -1 -1 -1 -1 -1 -1 -1 -1 -2 0 0 -2 -1 -1
> -1 -1 -1 ";
>
> return result;
> }
>
>
> public static void main (String args[]) {
> String seq1=
> "RRRVTVRKADAGGLGISIKGGRENKMPILISKIFKGLAADQTEALFVGDAILSVNGEDLSSATHDEAVQALKKTGKEVVLEVKYMK";
> //String seq2=
> "RRRVTVRKADAGGLGISIKGGRENKMPILISSIFKGLAADQTEALFVGDAILSVNGEDLSSATHDEAVQALKKTGKEVVLEVKYMK";
> String seq2=
> "LGEEDIPREPRRIVIHRGSTGLGFNIVGGEDGEGIFISFILAGGPADLSGELRKGDQILSVNGVDLRNASHEQAAIALKNAGQTVTIIAQYKPEEYSRFEAN";
> PairWiseAlignment test = PairWiseAlignment.alignProteins( seq1,
> seq2 ) ;
> System.err.println("PID 1: " + test.getPid1() + "\n" +
> test.getAln1() + "\n");
> System.err.println("PID 2: " + test.getPid2() + "\n" +
> test.getAln2() + "\n");
>
> }
>
>
> public int getScore() {
> return score;
> }
>
>
> public void setScore(int score) {
> this.score = score;
> }
>
>
> public int getScore2() {
> return score2;
> }
>
>
> public void setScore2(int score2) {
> this.score2 = score2;
> }
>
>
> public String getAln1() {
> return aln1;
> }
>
>
> public void setAln1(String aln1) {
> this.aln1 = aln1;
> }
>
>
> public String getAln2() {
> return aln2;
> }
>
>
> public void setAln2(String aln2) {
> this.aln2 = aln2;
> }
>
>
> public String getSeq1() {
> return seq1;
> }
>
> public String getSeq2() {
> return seq2;
> }
>
> public double getPid1() {
> return pid1;
> }
>
> public double getPid2() {
> return pid2;
> }
>
> public double getPID(String s1, String s2, String aln) {
> // Calculate the Percent Sequence Identity for the alignment
> // using the 'arithmetic mean sequence' length as the denominator
> // 'Percent Sequence IdentityThe Need to Be Explicit'
> // (2004) Alex C. W. May
> double arthMean = ((double) s1.length() + s2.length() ) / 2.0;
> int identicalChars = count(aln, '|');
> double result =((double) identicalChars )/ arthMean;
> return result;
> }
>
>
> public int count(String sourceString, char lookFor) {
> if (sourceString == null) {
> return -1;
> }
> int count = 0;
> for (int i = 0; i < sourceString.length(); i++) {
> final char c = sourceString.charAt(i);
> if (c == lookFor) {
> count++;
> }
> }
> return count;
> }
> }
>
>
> ----------------------------------------------------------------
>
>
>
> On 12/07/2010 06:11 PM, Chris Friedline wrote:
>
> Hi John,
>
> I do this all the time and at (very) quick glance your code looks fine
> from what I can remember about the legacy 1.7.1 codebase. However, when I
> did it, I normally loaded from external substitution matrix files
> (downloaded from NCBI) and used the PROTEIN-TERM alphabet.
>
> You might also want to get going with the BioJava3 libraries. I'm seeing
> a pretty big boost in performance now with beta2 and less code (~11k/sec on
> 8 CPUs).
>
> I also had some issues a while back with BioJava 1.7.1 and protein
> alignments that were fixed in the subversion repo, but not made part of the
> main binary release on biojava.org. You might want to download and
> compile the 1.7.1 dev version and try those libraries, as well. There are
> some changes that haven't made it into the wiki with the dev version 1.7.1
> (as I recall), but it's pretty straightforward to get it to work almost like
> what you have below.
>
> Chris
>
> On Tue, Dec 7, 2010 at 11:26 AM, John Hawkins <
> john.hawkins at biotec.tu-dresden.de> wrote:
>
>> Hi All,
>>
>> I have searched the archives of this list to try and solve my problem
>> and I can not find an answer.
>>
>> I am attempting to use BioJava to perform some pairwise alignments of
>> protein sequences.
>>
>> I have written a simple test class to check the functionality, and I am
>> getting an exception which does not make sense to me.
>>
>> Using the code below I receive the Exception
>>
>> org.biojava.bio.BioRuntimeException: Alphabet missmatch occured:
>> sequences with different alphabet cannot be aligned.
>> at
>>
>> org.biojava.bio.alignment.NeedlemanWunsch.pairwiseAlignment(NeedlemanWunsch.java:635)
>> at utilities.PairWiseAlignment.alignProteins(PairWiseAlignment.java:68)
>> at utilities.PairWiseAlignment.main(PairWiseAlignment.java:184)
>>
>> This is occuring even when I input two identical protein sequences (as
>> Strings).
>> It appears that the ProteinTools.createProteinSequence method generates
>> a unique alphabet for each sequence it is given,
>> and I cannot see any way to force the resulting sequence to have the
>> same underlying alphabet.
>>
>> Please forgive me I have overlooked something obvious.
>>
>> Regards
>> John Hawkins
>>
>> ----------------------------------------------------------------------------------------------------------------------------
>> package utilities;
>>
>> import org.biojava.bio.alignment.NeedlemanWunsch;
>> import org.biojava.bio.alignment.SequenceAlignment;
>> import org.biojava.bio.alignment.SmithWaterman;
>> import org.biojava.bio.alignment.SubstitutionMatrix;
>> import org.biojava.bio.seq.ProteinTools;
>> import org.biojava.bio.seq.Sequence;
>> import org.biojava.bio.symbol.AlphabetManager;
>> import org.biojava.bio.symbol.FiniteAlphabet;
>>
>>
>> public class PairWiseAlignment {
>>
>> private int score;
>> private int score2;
>> private String aln1;
>> private String aln2;
>>
>> public PairWiseAlignment(int score, int score2, String aln1,
>> String aln2) {
>> super();
>> this.score = score;
>> this.score2 = score2;
>> this.aln1 = aln1;
>> this.aln2 = aln2;
>> }
>>
>>
>> /** This performs an alignment of two given sequences and
>> * returns the result in an object.
>> *
>> * @param seq1 a query sequence
>> * @param seq2 a target sequence
>> */
>> public static PairWiseAlignment alignProteins(String seq1, String
>> seq2) {
>> int score = 0;
>> int score2 = 0;
>> String aln1= "";
>> String aln2= "";
>> try {
>> // The alphabet of the sequences. For this example DNA is
>> choosen.
>> FiniteAlphabet alphabet = (FiniteAlphabet)
>> AlphabetManager.alphabetForName("PROTEIN");
>> // Read the substitution matrix file.
>> // For this example the matrix NUC.4.4 is good.
>> SubstitutionMatrix matrix = new SubstitutionMatrix(alphabet,
>> PairWiseAlignment.getSubstitutionMatrix(), "BLOSUM62");
>> // Define the default costs for sequence manipulation for the
>> global alignment.
>> SequenceAlignment aligner = new NeedlemanWunsch(
>> (short) 0, // match
>> (short) 3, // replace
>> (short) 2, // insert
>> (short) 2, // delete
>> (short) 1, // gapExtend
>> matrix // SubstitutionMatrix
>> );
>> Sequence query = ProteinTools.createProteinSequence(seq1,
>> "query");
>> Sequence target = ProteinTools.createProteinSequence(seq2,
>> "target");
>>
>> System.err.println("ALPHA 1: " + query.getAlphabet() );
>> System.err.println("ALPHA 2: " + target.getAlphabet() );
>>
>> // Perform an alignment and save the results.
>> score = aligner.pairwiseAlignment(
>> query, // first sequence
>> target // second one
>> );
>> // Print the alignment to the screen
>> aln1 = "Global alignment with Needleman-Wunsch:\n" +
>> aligner.getAlignmentString();
>>
>> // Perform a local alginment from the sequences with
>> Smith-Waterman.
>> // Firstly, define the expenses (penalties) for every single
>> operation.
>> aligner = new SmithWaterman(
>> (short) -1, // match
>> (short) 3, // replace
>> (short) 2, // insert
>> (short) 2, // delete
>> (short) 1, // gapExtend
>> matrix // SubstitutionMatrix
>> );
>> // Perform the local alignment.
>> score2 = aligner.pairwiseAlignment(query, target);
>>
>> aln2 = "\nlocal alignment with SmithWaterman:\n" +
>> aligner.getAlignmentString();
>> } catch (Exception exc) {
>> exc.printStackTrace();
>> }
>>
>> return new PairWiseAlignment(score, score2, aln1, aln2);
>>
>> }
>>
>> public static String getSubstitutionMatrix() {
>> //TODO: Load this as a resource
>> String result = "# Matrix made by matblas from
>> blosum62.iij \n" +
>> "# * column uses minimum score\n" +
>> "# BLOSUM Clustered Scoring Matrix in 1/2 Bit Units\n" +
>> "# Blocks Database = /data/blocks_5.0/blocks.dat\n" +
>> "# Cluster Percentage: >= 62\n" +
>> "# Entropy = 0.6979, Expected = -0.5209\n" +
>> " A R N D C Q E G H I L K M F P S T W Y
>> V B Z X \n" +
>> "A 4 -1 -2 -2 0 -1 -1 0 -2 -1 -1 -1 -1 -2 -1 1 0 -3 -2
>> 0 -2 -1 0 \n" +
>> "R -1 5 0 -2 -3 1 0 -2 0 -3 -2 2 -1 -3 -2 -1 -1 -3 -2
>> -3 -1 0 -1 \n" +
>> "N -2 0 6 1 -3 0 0 0 1 -3 -3 0 -2 -3 -2 1 0 -4 -2
>> -3 3 0 -1 \n" +
>> "D -2 -2 1 6 -3 0 2 -1 -1 -3 -4 -1 -3 -3 -1 0 -1 -4 -3
>> -3 4 1 -1 \n" +
>> "C 0 -3 -3 -3 9 -3 -4 -3 -3 -1 -1 -3 -1 -2 -3 -1 -1 -2 -2
>> -1 -3 -3 -2 \n" +
>> "Q -1 1 0 0 -3 5 2 -2 0 -3 -2 1 0 -3 -1 0 -1 -2 -1
>> -2 0 3 -1 \n" +
>> "E -1 0 0 2 -4 2 5 -2 0 -3 -3 1 -2 -3 -1 0 -1 -3 -2
>> -2 1 4 -1 \n" +
>> "G 0 -2 0 -1 -3 -2 -2 6 -2 -4 -4 -2 -3 -3 -2 0 -2 -2 -3
>> -3 -1 -2 -1 \n" +
>> "H -2 0 1 -1 -3 0 0 -2 8 -3 -3 -1 -2 -1 -2 -1 -2 -2 2
>> -3 0 0 -1 \n" +
>> "I -1 -3 -3 -3 -1 -3 -3 -4 -3 4 2 -3 1 0 -3 -2 -1 -3 -1
>> 3 -3 -3 -1 \n" +
>> "L -1 -2 -3 -4 -1 -2 -3 -4 -3 2 4 -2 2 0 -3 -2 -1 -2 -1
>> 1 -4 -3 -1 \n" +
>> "K -1 2 0 -1 -3 1 1 -2 -1 -3 -2 5 -1 -3 -1 0 -1 -3 -2
>> -2 0 1 -1 \n" +
>> "M -1 -1 -2 -3 -1 0 -2 -3 -2 1 2 -1 5 0 -2 -1 -1 -1 -1
>> 1 -3 -1 -1 \n" +
>> "F -2 -3 -3 -3 -2 -3 -3 -3 -1 0 0 -3 0 6 -4 -2 -2 1 3
>> -1 -3 -3 -1 \n" +
>> "P -1 -2 -2 -1 -3 -1 -1 -2 -2 -3 -3 -1 -2 -4 7 -1 -1 -4 -3
>> -2 -2 -1 -2 \n" +
>> "S 1 -1 1 0 -1 0 0 0 -1 -2 -2 0 -1 -2 -1 4 1 -3 -2
>> -2 0 0 0 \n" +
>> "T 0 -1 0 -1 -1 -1 -1 -2 -2 -1 -1 -1 -1 -2 -1 1 5 -2 -2
>> 0 -1 -1 0 \n" +
>> "W -3 -3 -4 -4 -2 -2 -3 -2 -2 -3 -2 -3 -1 1 -4 -3 -2 11 2
>> -3 -4 -3 -2 \n" +
>> "Y -2 -2 -2 -3 -2 -1 -2 -3 2 -1 -1 -2 -1 3 -3 -2 -2 2 7
>> -1 -3 -2 -1 \n" +
>> "V 0 -3 -3 -3 -1 -2 -2 -3 -3 3 1 -2 1 -1 -2 -2 0 -3 -1
>> 4 -3 -2 -1 \n" +
>> "B -2 -1 3 4 -3 0 1 -1 0 -3 -4 0 -3 -3 -2 0 -1 -4 -3
>> -3 4 1 -1 \n" +
>> "Z -1 0 0 1 -3 3 4 -2 0 -3 -3 1 -1 -3 -1 0 -1 -3 -2
>> -2 1 4 -1 \n" +
>> "X 0 -1 -1 -1 -2 -1 -1 -1 -1 -1 -1 -1 -1 -1 -2 0 0 -2 -1
>> -1 -1 -1 -1 ";
>>
>> return result;
>> }
>>
>>
>> public static void main (String args[]) {
>> String seq1=
>>
>> "RRRVTVRKADAGGLGISIKGGRENKMPILISKIFKGLAADQTEALFVGDAILSVNGEDLSSATHDEAVQALKKTGKEVVLEVKYMK";
>> String seq2=
>>
>> "LGEEDIPREPRRIVIHRGSTGLGFNIVGGEDGEGIFISFILAGGPADLSGELRKGDQILSVNGVDLRNASHEQAAIALKNAGQTVTIIAQYKPEEYSRFEAN";
>> PairWiseAlignment test = PairWiseAlignment.alignProteins(
>> seq2, seq2 ) ;
>> System.err.println("SCORE 1: " + test.score + "\n" +
>> test.getAln1() + "\n");
>> System.err.println("SCORE 2: " + test.score2 + "\n" +
>> test.getAln2() + "\n");
>> }
>>
>>
>> public int getScore() {
>> return score;
>> }
>>
>>
>> public void setScore(int score) {
>> this.score = score;
>> }
>>
>>
>> public int getScore2() {
>> return score2;
>> }
>>
>>
>> public void setScore2(int score2) {
>> this.score2 = score2;
>> }
>>
>>
>> public String getAln1() {
>> return aln1;
>> }
>>
>>
>> public void setAln1(String aln1) {
>> this.aln1 = aln1;
>> }
>>
>>
>> public String getAln2() {
>> return aln2;
>> }
>>
>>
>> public void setAln2(String aln2) {
>> this.aln2 = aln2;
>> }
>> }
>>
>>
>> -------------------------------------------------------------------------------------------------------
>>
>>
>> --
>>
>> Dr John Hawkins
>> Post-Doctoral Researcher
>>
>> Technische Universität Dresden
>> Biotechnology Center
>> Tatzberg 47/49
>> 01307 Dresden
>>
>> Tel.: +49 (0) 351 463-40083
>> Fax: +49 (0) 351 463-40087
>> E-Mail: john.hawkins at biotec.tu-dresden
>> Webpage: www.biotec.tu-dresden.de
>>
>> _______________________________________________
>> biojava-dev mailing list
>> biojava-dev at lists.open-bio.org
>> http://lists.open-bio.org/mailman/listinfo/biojava-dev
>>
>
>
>
> --
> PhD Candidate, Integrative Life Sciences
> Virginia Commonwealth University
> Richmond, VA
>
>
>
> --
>
> Dr John Hawkins
> Post-Doctoral Researcher
>
> Technische Universität Dresden
> Biotechnology Center
> Tatzberg 47/49
> 01307 Dresden
>
> Tel.: +49 (0) 351 463-40083
> Fax: +49 (0) 351 463-40087
> E-Mail: john.hawkins at biotec.tu-dresden
>
> Webpage: www.biotec.tu-dresden.de
>
>
--
PhD Candidate, Integrative Life Sciences
Virginia Commonwealth University
Richmond, VA
More information about the biojava-dev
mailing list