/**\r
* Load the (T-Coffee) score file from the specified url \r
* \r
- * @param url The absolute path from where download and read the score file\r
+ * @param source File/URL/T-COFFEE score file contents\r
* @throws IOException \r
+ * @return true if alignment was annotated with data from source\r
*/\r
- public void loadScoreFile( URL url ) throws IOException {\r
- // TODO: refactor to string/standard jalview data importer\r
- TCoffeeScoreFile file = TCoffeeScoreFile.load( new InputStreamReader( url.openStream() ) );\r
- if( file == null ) {\r
- // TODO: raise a dialog box here rather than bomb out.\r
- \r
- throw new RuntimeException("The file provided does not match the T-Coffee scores file format");\r
+ public boolean loadScoreFile( String source ) throws IOException {\r
+\r
+ TCoffeeScoreFile file = new TCoffeeScoreFile(source, AppletFormatAdapter.checkProtocol(source));\r
+ if( !file.isValid()) {\r
+ // TODO: raise dialog for gui\r
+ System.err.println("Problems parsing T-Coffee scores: "+file.getWarningMessage());\r
+ System.err.println("Origin was:\n"+source);\r
+ return false;\r
}\r
\r
/*\r
AlignmentI aln; \r
if( (aln=viewport.getAlignment()) != null && (aln.getHeight() != file.getHeight() || aln.getWidth() != file.getWidth()) ) {\r
// TODO: raise a dialog box here rather than bomb out.\r
- throw new RuntimeException("The scores matrix does not match the alignment dimensions");\r
+ System.err.println("The scores matrix does not match the alignment dimensions");\r
\r
}\r
\r
// TODO add parameter to indicate if matching should be done\r
if (file.annotateAlignment(alignPanel.getAlignment(), false))\r
{\r
- tcoffeeColour.setEnabled(true);\r
+ alignPanel.fontChanged();\r
+ tcoffeeColour.setEnabled(true);\r
// switch to this color\r
changeColour(new TCoffeeColourScheme(alignPanel.getAlignment()));\r
+ return true;\r
+ } else {\r
+ System.err.println("Problems resolving T-Coffee scores:");\r
+ if (file.getWarningMessage()!=null) {\r
+ System.err.println(file.getWarningMessage());\r
+ }\r
}\r
+ return false;\r
}\r
\r
\r
* @author Paolo Di Tommaso
*
*/
-public class TCoffeeScoreFile {
+public class TCoffeeScoreFile extends AlignFile {
+ public TCoffeeScoreFile(String inFile, String type) throws IOException
+ {
+ super(inFile, type);
+
+ }
+
+ public TCoffeeScoreFile(FileParse source) throws IOException
+ {
+ super(source);
+ }
+
/** The {@link Header} structure holder */
Header header;
* Holds the consensues values for each sequences. It uses a LinkedHashMap to maintaint the
* insertion order.
*/
- LinkedHashMap<String,StringBuilder> scores = new LinkedHashMap<String,StringBuilder>();
+ LinkedHashMap<String,StringBuilder> scores;
Integer fWidth;
-
- /**
- * Parse the specified file.
- *
- * @param file The file to be parsed
- */
- public static TCoffeeScoreFile load(File file) {
- try {
- return load(new FileReader(file));
- }
- catch (FileNotFoundException e) {
- throw new RuntimeException(e);
- }
- }
/**
* Parse the provided reader for the T-Coffee scores file format
*
* @param reader
- */
public static TCoffeeScoreFile load(Reader reader) {
try {
throw new RuntimeException(e);
}
}
+ */
/**
* @return The 'height' of the score matrix i.e. the numbers of score rows that should matches
return fWidth != null ? fWidth : 0;
}
- /**
- * The default constructor is marked as {@code protected} since this class is meant to created
- * through the {@link #load(File)} or {@link #load(Reader)} factory methods
- */
- protected TCoffeeScoreFile() { }
/**
* Get the string of score values for the specified seqeunce ID.
* It return an empty string when the specified ID is missing.
*/
public String getScoresFor( String id ) {
- return scores.containsKey(id) ? scores.get(id).toString() : "";
+ return scores!=null && scores.containsKey(id) ? scores.get(id).toString() : "";
}
/**
* @return The list of score string as a {@link List} object, in the same ordeer of the insertion i.e. in the MSA
*/
public List<String> getScoresList() {
+ if (scores==null)
+ {
+ return null;
+ }
List<String> result = new ArrayList<String>( scores.size() );
for( Map.Entry<String,StringBuilder> it : scores.entrySet() ) {
result.add(it.getValue().toString());
* @return The parsed score values a matrix of bytes
*/
public byte[][] getScoresArray() {
+ if (scores==null)
+ {
+ return null;
+ }
byte[][] result = new byte[ scores.size() ][];
int rowCount = 0;
}
- private void doParsing(BufferedReader in) throws IOException {
-
+ public void parse() throws IOException
+ {
/*
* read the header
*/
- header = readHeader(in);
+ header = readHeader(this);
- if( header == null ) { return; }
-
+ if( header == null ) { error=true; return;}
+ scores = new LinkedHashMap<String,StringBuilder>();
/*
* initilize the structure
* go with the reading
*/
Block block;
- while( (block = readBlock(in, header.scores.size())) != null ) {
+ while( (block = readBlock(this,header.scores.size())) != null ) {
/*
* append sequences read in the block
for( Map.Entry<String,String> entry : block.items.entrySet() ) {
StringBuilder scoreStringBuilder = scores.get(entry.getKey());
if( scoreStringBuilder == null ) {
- throw new RuntimeException(String.format("Invalid T-Coffee score file: Sequence ID '%s' is not declared in header section", entry.getKey()));
+ error=true;
+ errormessage=String.format("Invalid T-Coffee score file: Sequence ID '%s' is not declared in header section", entry.getKey());
+ return ;
}
scoreStringBuilder.append( entry.getValue() );
fWidth = str.length();
}
else if( fWidth != str.length() ) {
- throw new RuntimeException("Invalid T-Coffee score file: All the score sequences must have the same length");
+ error=true;
+ errormessage="Invalid T-Coffee score file: All the score sequences must have the same length";
+ return ;
}
}
-
+ return;
}
* @return The parser {@link Header} instance
* @throws RuntimeException when the header is not in the expected format
*/
- static Header readHeader(BufferedReader reader) {
+ static Header readHeader(FileParse reader) throws IOException {
Header result = null;
try {
result = new Header();
- result.head = reader.readLine();
+ result.head = reader.nextLine();
String line;
- while( (line = reader.readLine()) != null ) {
+ while( (line = reader.nextLine()) != null ) {
if( line.startsWith("SCORE=")) {
result.score = parseInt( line.substring(6).trim() );
break;
}
}
- if( (line=reader.readLine())==null || !"*".equals(line.trim())) return null;
- if( (line=reader.readLine())==null || !"BAD AVG GOOD".equals(line.trim())) return null;
- if( (line=reader.readLine())==null || !"*".equals(line.trim())) return null;
+ if( (line=reader.nextLine())==null || !"*".equals(line.trim())) { error(reader,"Invalid T-COFFEE score format (NO BAD/AVG/GOOD header)"); return null;}
+ if( (line=reader.nextLine())==null || !"BAD AVG GOOD".equals(line.trim())) { error(reader,"Invalid T-COFFEE score format (NO BAD/AVG/GOOD header)"); return null;}
+ if( (line=reader.nextLine())==null || !"*".equals(line.trim())) {error(reader,"Invalid T-COFFEE score format (NO BAD/AVG/GOOD header)"); return null;}
/*
* now are expected a list if sequences ID up to the first blank line
*/
- while( (line=reader.readLine()) != null ) {
+ while( (line=reader.nextLine()) != null ) {
if( "".equals(line) ) {
break;
}
result.scores.put(id,val);
}
+ if (result==null) {
+ error(reader, "T-COFFEE score file had no per-sequence scores");
+ }
+
}
catch( IOException e ) {
- throw new RuntimeException("Cannot parse T-Coffee score ascii file", e);
+ error(reader,"Unexpected problem parsing T-Coffee score ascii file");
+ throw e;
}
return result;
}
-
+ private static void error(FileParse reader, String errm)
+ {
+ reader.error=true;
+ if (reader.errormessage==null)
+ { reader.errormessage=errm;
+ } else {
+ reader.errormessage+="\n"+errm;
+ }
+ }
/**
* Read a scores block ihe provided stream.
*
* @return The {@link Block} instance read or {link null} null if the end of file has reached.
* @throws IOException Something went wrong on the 'wire'
*/
- static Block readBlock( BufferedReader reader, int size ) throws IOException {
+ static Block readBlock( FileParse reader, int size ) throws IOException {
Block result = new Block(size);
String line;
/*
* read blank lines (eventually)
*/
- while( (line=reader.readLine()) != null && "".equals(line.trim())) {
+ while( (line=reader.nextLine()) != null && "".equals(line.trim())) {
// consume blank lines
}
- if( line == null ) return null;
+ if( line == null ) { return null; }
/*
* read the scores block
// split the line on the first blank
// the first part have to contain the sequence id
- // theramining part are the scores values
+ // the remaining part are the scores values
int p = line.indexOf(" ");
if( p == -1 ) {
- //TODO This is an unexpected condition, log a warning or throw an exception ?
- continue;
+ if (reader.warningMessage==null) { reader.warningMessage=""; }
+ reader.warningMessage+="Possible parsing error - expected to find a space in line: '"+line+"'\n";
+ continue;
}
String id = line.substring(0,p).trim();
result.items.put(id, val);
- } while( (line = reader.readLine()) != null );
+ } while( (line = reader.nextLine()) != null );
return result;
*/
public boolean annotateAlignment(AlignmentI al, boolean matchids)
{
+ if (al.getHeight()!=getHeight() || al.getWidth()!=getWidth())
+ {
+ warningMessage="Alignment shape does not match T-Coffee score file shape.";
+ return false;
+ }
boolean added=false;
int i=0;
SequenceIdMatcher sidmatcher = new SequenceIdMatcher(al.getSequencesArray());
byte val = srow[j];
annotations[j]=new Annotation(s==null ? ""+val:null,s==null ? ""+val:null,(char) val,val*1f,val >= 0 && val < colors.length ? colors[val] : Color.white);
}
- AlignmentAnnotation aa=null;
+ // this will overwrite any existing t-coffee scores for the alignment
+ AlignmentAnnotation aa=al.findOrCreateAnnotation(TCOFFEE_SCORE,false,s,null);
if (s!=null)
{
- // TODO - set per sequence score
- aa=new AlignmentAnnotation(TCOFFEE_SCORE, "Score for "+id.getKey(), annotations);
-
- aa.setSequenceRef(s);
+ aa.label="T-COFFEE";
+ aa.description="Score for "+id.getKey();
+ aa.annotations=annotations;
aa.visible=false;
aa.belowAlignment=false;
} else {
- aa=new AlignmentAnnotation("T-COFFEE", "TCoffee column reliability score", annotations);
+ aa.graph=AlignmentAnnotation.NO_GRAPH;
+ aa.label="T-COFFEE";
+ aa.description="TCoffee column reliability score";
+ aa.annotations=annotations;
aa.belowAlignment=true;
aa.visible=true;
-
}
- al.addAnnotation(aa);
+ aa.showAllColLabels=true;
+ aa.setSequenceRef(s);
+ aa.validateRangeAndDisplay();
added=true;
}
return added;
}
-
+ @Override
+ public String print()
+ {
+ // TODO Auto-generated method stub
+ return "Not valid.";
+ }
}
public class TCoffeeScoreFileTest {
- final static File SCORE_FILE = new File("./test/jalview/io/tcoffee.score_ascii");
+ final static File SCORE_FILE = new File("test/jalview/io/tcoffee.score_ascii");
+ final static File ALIGN_FILE = new File("test/jalview/io/tcoffee.fasta_aln");
@Test
- public void testReadHeader() throws FileNotFoundException {
+ public void testReadHeader() throws IOException, FileNotFoundException {
- Header header = TCoffeeScoreFile.readHeader( new BufferedReader(new FileReader(SCORE_FILE)) );
+ TCoffeeScoreFile scoreFile = new TCoffeeScoreFile(SCORE_FILE.getPath(),AppletFormatAdapter.FILE);
+ assertTrue(scoreFile.getWarningMessage(),scoreFile.isValid());
+ Header header = scoreFile.header;
assertNotNull(header);
assertEquals( "T-COFFEE, Version_9.02.r1228 (2012-02-16 18:15:12 - Revision 1228 - Build 336)", header.head );
assertEquals( 90, header.score );
@Test
public void testWrongFile() {
- TCoffeeScoreFile result = TCoffeeScoreFile.load(new File("./test/jalview/io/tcoffee.fasta_aln"));
- assertNull(result);
+ try {
+ TCoffeeScoreFile result = new TCoffeeScoreFile(ALIGN_FILE.getPath(), FormatAdapter.FILE);
+ assertFalse(result.isValid());
+ } catch (IOException x)
+ {
+ assertTrue("File not found exception thrown",x instanceof FileNotFoundException);
+ }
}
@Test
- public void testHeightAndWidth() {
- TCoffeeScoreFile result = TCoffeeScoreFile.load(new File("./test/jalview/io/tcoffee.score_ascii"));
- assertNotNull(result);
+ public void testHeightAndWidth() throws IOException {
+ TCoffeeScoreFile result = new TCoffeeScoreFile(SCORE_FILE.getPath(), FormatAdapter.FILE);
+ assertTrue(result.isValid());
assertEquals( 8, result.getHeight() );
assertEquals( 83, result.getWidth() );
}
"cons 999999999999999999999999999851000110321100001134\n" +
"\n" +
"\n";
-
- Block block = TCoffeeScoreFile.readBlock(new BufferedReader(new StringReader(BLOCK)), 0);
- assertNotNull(block);
+ FileParse source=new FileParse(BLOCK, FormatAdapter.PASTE);
+ Block block = TCoffeeScoreFile.readBlock(source, 0);
+
+ assertNotNull(block);
assertEquals( "999999999999999999999999998762112222543211112134", block.getScoresFor("1PHT") );
assertEquals( "99999999999999999999999999987-------4322----2234", block.getScoresFor("1BB9") );
assertEquals( "99999999999999999999999999987-------5321----2246", block.getScoresFor("1UHC") );
}
@Test
- public void testParse() throws FileNotFoundException {
+ public void testParse() throws IOException {
- TCoffeeScoreFile parser = TCoffeeScoreFile.load(new BufferedReader(new FileReader(SCORE_FILE)) );
+ TCoffeeScoreFile parser = new TCoffeeScoreFile(SCORE_FILE.getPath(), FormatAdapter.FILE);
assertEquals( "999999999999999999999999998762112222543211112134----------5666642367889999999999889", parser.getScoresFor("1PHT") );
assertEquals( "99999999999999999999999999987-------4322----22341111111111676653-355679999999999889", parser.getScoresFor("1BB9") );
@Test
- public void testGetAsList() throws FileNotFoundException {
+ public void testGetAsList() throws IOException {
- TCoffeeScoreFile parser = TCoffeeScoreFile.load(new BufferedReader(new FileReader(SCORE_FILE)) );
-
+ TCoffeeScoreFile parser = new TCoffeeScoreFile(SCORE_FILE.getPath(),FormatAdapter.FILE);
+ assertTrue(parser.getWarningMessage(),parser.isValid());
List<String> scores = parser.getScoresList();
assertEquals( "999999999999999999999999998762112222543211112134----------5666642367889999999999889", scores.get(0) );
assertEquals( "99999999999999999999999999987-------4322----22341111111111676653-355679999999999889", scores.get(1) );
@Test
- public void testGetAsArray() throws FileNotFoundException {
+ public void testGetAsArray() throws IOException {
- TCoffeeScoreFile parser = TCoffeeScoreFile.load(new BufferedReader(new FileReader(SCORE_FILE)) );
-
+ TCoffeeScoreFile parser = new TCoffeeScoreFile(SCORE_FILE.getPath(),FormatAdapter.FILE);
+ assertTrue(parser.getWarningMessage(),parser.isValid());
byte[][] scores = parser.getScoresArray();
assertEquals( 9, scores[0][0] );