/*
* EuroCarbDB, a framework for carbohydrate bioinformatics
*
* Copyright (c) 2006-2009, Eurocarb project, or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
* A copy of this license accompanies this distribution in the file LICENSE.txt.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* Last commit: $Rev: 1210 $ by $Author: glycoslave $ on $Date:: 2009-06-12 #$
*/
package org.eurocarbdb.application.glycanbuilder;
import java.util.Collection;
import java.util.Iterator;
import java.util.TreeMap;
import java.util.HashMap;
import java.util.Vector;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileNotFoundException;
/**
The dictionary of all residue types available in the application.
Information about residue types is loaded at run time from a
configuration file. The dictionary is a singleton and all
information has class-wide access.
@see Residue
@see ResidueType
@author Alessio Ceroni (a.ceroni@imperial.ac.uk)
*/
public class ResidueDictionary {
static {
dictionary = new HashMap<String,ResidueType>();
superclasses = new Vector<String>();
direct_residues = new TreeMap<Integer,ResidueType>();
other_residues = new Vector<ResidueType>();
all_residues = new Vector<ResidueType>();
all_residues_map = new HashMap<String,Vector<ResidueType> >();
initDictionary();
}
private static HashMap<String,ResidueType> dictionary;
private static Vector<String> superclasses;
private static TreeMap<Integer,ResidueType> direct_residues;
private static Vector<ResidueType> other_residues;
private static Vector<ResidueType> all_residues;
private static HashMap<String,Vector<ResidueType> > all_residues_map;
// --- Data access
/**
Return the residue type with the given name
@see ResidueType
@throws Exception if there is no residue type with such a name
*/
public static ResidueType getResidueType(String type_name) throws Exception{
ResidueType ret = findResidueType(type_name);
if( ret==null )
throw new Exception("Invalid type: <" + type_name + ">");
return ret;
}
/**
Return <code>true</code> if a residue type with such a name
exists.
@see ResidueType
*/
public static boolean hasResidueType(String type_name) {
return (findResidueType(type_name)!=null);
}
/**
Return the residue type with the given name or
<code>null</null> otherwise
@see ResidueType
*/
public static ResidueType findResidueType(String type_name) {
ResidueType ret = dictionary.get(type_name.toLowerCase());
if( ret!=null )
return ret;
if( type_name.indexOf('=')!=-1 ) {
String[] tokens = type_name.split("=");
String name = tokens[0];
double mass = Double.valueOf(tokens[1].substring(0,tokens[1].length()-1));
return ResidueType.createOtherReducingEnd(name,mass);
}
return null;
}
/**
Return an iterator over all residue types.
*/
public static Iterator<ResidueType> iterator() {
return all_residues.iterator();
}
protected static Collection<ResidueType> directResidues() {
return direct_residues.values();
}
protected static Collection<ResidueType> otherResidues() {
return other_residues;
}
/**
Return the collection of all residue types.
*/
public static Collection<ResidueType> allResidues() {
return all_residues;
}
/**
Return the collection of all residue classes.
*/
public static Collection<String> getSuperclasses() {
return superclasses;
}
/**
Return the collection of all residue types in a specific
class.
*/
public static Collection<ResidueType> getResidues(String superclass) {
return all_residues_map.get(superclass);
}
/**
Return the collection of all reducing end marker types.
*/
public static Collection<ResidueType> getReducingEnds() {
Vector<ResidueType> ret = new Vector<ResidueType>();
for( ResidueType rt : all_residues ) {
if( rt.canBeReducingEnd() )
ret.add(rt);
}
return ret;
}
/**
Return the collection of all names of reducing end marker
types.
*/
public static Collection<String> getReducingEndsString() {
Vector<String> ret = new Vector<String>();
for( ResidueType rt : all_residues ) {
if( rt.canBeReducingEnd() )
ret.add(rt.getName());
}
return ret;
}
//
/**
Create a new residue of a type specified by its name.
@throws Exception if no residue type with the specified name
exists
*/
public static Residue newResidue(String type_name) throws Exception {
return new Residue(getResidueType(type_name));
}
/**
Create a free reducing end marker.
@see ResidueType#createFreeReducingEnd
*/
public static Residue createReducingEnd() {
return new Residue(findResidueType("freeEnd"));
}
/**
Create a begin repeat block residue.
@see ResidueType#createStartRepetition
*/
public static Residue createStartRepetition() {
return new Residue(findResidueType("#startrep"));
}
/**
Create a end repeat block residue.
@see ResidueType#createEndRepetition
*/
public static Residue createEndRepetition() {
return new Residue(findResidueType("#endrep_?_?"));
}
/**
Create a end repeat block residue with a specified interval.
@see ResidueType#createEndRepetition
*/
public static Residue createEndRepetition(String min, String max) {
return new Residue(ResidueType.createEndRepetition(min,max));
}
/**
Create a bracket residue.
@see ResidueType#createBracket
*/
public static Residue createBracket() {
return new Residue(findResidueType("#bracket"));
}
/**
Create an attach point.
@see ResidueType#createAttachPoint
*/
public static Residue createAttachPoint() {
return new Residue(findResidueType("#attach"));
}
/**
Create a B cleavage.
@see ResidueType#createBCleavage
*/
static public Residue createBCleavage() {
return new Residue(findResidueType("#bcleavage"));
}
/**
Create a C cleavage.
@see ResidueType#createCCleavage
*/
static public Residue createCCleavage() {
return new Residue(findResidueType("#ccleavage"));
}
/**
Create a Y cleavage.
@see ResidueType#createYCleavage
*/
static public Residue createYCleavage() {
return new Residue(findResidueType("#ycleavage"));
}
/**
Create a Z cleavage.
@see ResidueType#createZCleavage
*/
static public Residue createZCleavage() {
return new Residue(findResidueType("#zcleavage"));
}
/**
Create a labile cleavage.
@see ResidueType#createLCleavage
*/
static public Residue createLCleavage() {
return new Residue(findResidueType("#lcleavage"));
}
//---- init
private ResidueDictionary() {}
/**
Load the residue types from a configuration file.
*/
public static void loadDictionary(String filename) {
// clear dict
initDictionary();
superclasses.clear();
direct_residues.clear();
other_residues.clear();
all_residues.clear();
all_residues_map.clear();
try {
// open file
java.net.URL file_url = ResidueDictionary.class.getResource(filename);
if( file_url==null )
throw new FileNotFoundException(filename);
BufferedReader is = new BufferedReader(new InputStreamReader(file_url.openStream()));
// read dictionary
String line;
while( (line=is.readLine())!=null ) {
line = TextUtils.trim(line);
if( line.length()>0 && !line.startsWith("%") )
add(new ResidueType(line));
}
is.close();
}
catch(Exception e) {
LogUtils.report(e);
dictionary.clear();
}
}
private static void add(ResidueType type) {
dictionary.put(type.getName().toLowerCase(),type);
for( String s : type.getSynonyms() )
dictionary.put(s.toLowerCase(),type);
// add superclass
String superclass = type.getSuperclass();
if( all_residues_map.get(superclass)==null ) {
superclasses.add(superclass);
all_residues_map.put(superclass,new Vector<ResidueType>());
}
// collect residues
if( type.getToolbarOrder()!=0 )
direct_residues.put(type.getToolbarOrder(),type);
else
other_residues.add(type);
all_residues.add(type);
all_residues_map.get(superclass).add(type);
}
private static void initDictionary() {
dictionary.clear();
add(new ResidueType());
add(ResidueType.createAttachPoint());
add(ResidueType.createBracket());
add(ResidueType.createStartRepetition());
add(ResidueType.createEndRepetition());
add(ResidueType.createBCleavage());
add(ResidueType.createCCleavage());
add(ResidueType.createYCleavage());
add(ResidueType.createZCleavage());
add(ResidueType.createLCleavage());
if( dictionary.get("freeEnd")==null )
add(ResidueType.createFreeReducingEnd());
}
}