action.scale_right = Scale Right
action.by_tree_order = By Tree Order
action.sort = Sort
-action.calculate_tree = Calculate Tree
+action.calculate_tree = Calculate Tree...
action.help = Help
action.by_annotation = By Annotation...
action.invert_sequence_selection = Invert Sequence Selection
label.principal_component_analysis = Principal Component Analysis
label.average_distance_identity = Average Distance Using % Identity
label.neighbour_joining_identity = Neighbour Joining Using % Identity
+label.choose_tree = Choose Tree Calculation
label.treecalc_title = {0} Using {1}
label.tree_calc_av = Average Distance
label.tree_calc_nj = Neighbour Joining
label.set_this_label_text = set this label text
label.sequences_from = Sequences from {0}
label.successfully_loaded_file = Successfully loaded file {0}
+label.successfully_loaded_matrix = Successfully loaded score matrix {0}
label.successfully_saved_to_file_in_format = Successfully saved to file: {0} in {1} format.
label.copied_sequences_to_clipboard = Copied {0} sequences to clipboard.
label.check_file_matches_sequence_ids_alignment = Check that the file matches sequence IDs in the alignment.
label.principal_component_analysis = Análisis del Componente Principal
label.average_distance_identity = Distancia Media Usando % de Identidad
label.neighbour_joining_identity = Unir vecinos utilizando % de Identidad
+label.choose_tree = Elegir el cálculo del árbol
label.treecalc_title = {0} utilizando {1}
label.tree_calc_av = Distancia media
label.tree_calc_nj = Unir vecinos
--- /dev/null
+ScoreMatrix BLOSUM62
+ARNDCQEGHILKMFPSTWYVBZX *
+#
+# The BLOSUM62 substitution matrix, as at https://www.ncbi.nlm.nih.gov/Class/FieldGuide/BLOSUM62.txt
+# The first line declares a ScoreMatrix with the name BLOSUM62 (shown in menus)
+# The second line gives the symbols for which scores are held in the matrix
+# These may include a space (but not as the first or last character)
+#
+# Scores are not symbol case sensitive, unless column(s) are provided for lower case characters
+# The 'guide symbol' at the start of each row of score values is optional
+#
+# Comment header line with symbols is provided as a guide
+# Values may be integer or floating point, delimited by tab, space, comma or combinations
+#
+# A R N D C Q E G H I L K M F P S T W Y V B Z X *
+#
+A 4 -1 -2 -2 0 -1 -1 0 -2 -1 -1 -1 -1 -2 -1 1 0 -3 -2 0 -2 -1 0 -4 -4
+R -1 5 0 -2 -3 1 0 -2 0 -3 -2 2 -1 -3 -2 -1 -1 -3 -2 -3 -1 0 -1 -4 -4
+N -2 0 6 1 -3 0 0 0 1 -3 -3 0 -2 -3 -2 1 0 -4 -2 -3 3 0 -1 -4 -4
+D -2 -2 1 6 -3 0 2 -1 -1 -3 -4 -1 -3 -3 -1 0 -1 -4 -3 -3 4 1 -1 -4 -4
+C 0 3 -3 -3 9 -3 -4 -3 -3 -1 -1 -3 -1 -2 -3 -1 -1 -2 -2 -1 -3 -3 -2 -4 -4
+Q -1 1 0 0 -3 5 2 -2 0 -3 -2 1 0 -3 -1 0 -1 -2 -1 -2 0 3 -1 -4 -4
+E -1 0 0 2 -4 2 5 -2 0 -3 -3 1 -2 -3 -1 0 -1 -3 -2 -2 1 4 -1 -4 -4
+G 0 -2 0 -1 -3 -2 -2 6 -2 -4 -4 -2 -3 -3 -2 0 -2 -2 -3 -3 -1 -2 -1 -4 -4
+H -2 0 1 -1 -3 0 0 -2 8 -3 -3 -1 -2 -1 -2 -1 -2 -2 2 -3 0 0 -1 -4 -4
+I -1 -3 -3 -3 -1 -3 -3 -4 -3 4 2 -3 1 0 -3 -2 -1 -3 -1 3 -3 -3 -1 -4 -4
+L -1 -2 -3 -4 -1 -2 -3 -4 -3 2 4 -2 2 0 -3 -2 -1 -2 -1 1 -4 -3 -1 -4 -4
+K -1 2 0 -1 -3 1 1 -2 -1 -3 -2 5 -1 -3 -1 0 -1 -3 -2 -2 0 1 -1 -4 -4
+M -1 -1 -2 -3 -1 0 -2 -3 -2 1 2 -1 5 0 -2 -1 -1 -1 -1 1 -3 -1 -1 -4 -4
+F -2 -3 -3 -3 -2 -3 -3 -3 -1 0 0 -3 0 6 -4 -2 -2 1 3 -1 -3 -3 -1 -4 -4
+P -1 -2 -2 -1 -3 -1 -1 -2 -2 -3 -3 -1 -2 -4 7 -1 -1 -4 -3 -2 -2 -1 -2 -4 -4
+S 1 -1 1 0 -1 0 0 0 -1 -2 -2 0 -1 -2 -1 4 1 -3 -2 -2 0 0 0 -4 -4
+T 0 -1 0 -1 -1 -1 -1 -2 -2 -1 -1 -1 -1 -2 -1 1 5 -2 -2 0 -1 -1 0 -4 -4
+W -3 -3 -4 -4 -2 -2 -3 -2 -2 -3 -2 -3 -1 1 -4 -3 -2 11 2 -3 -4 -3 -2 -4 -4
+Y -2 -2 -2 -3 -2 -1 -2 -3 2 -1 -1 -2 -1 3 -3 -2 -2 2 7 -1 -3 -2 -1 -4 -4
+V 0 -3 -3 -3 -1 -2 -2 -3 -3 3 1 -2 1 -1 -2 -2 0 -3 -1 4 -3 -2 -1 -4 -4
+B -2 -1 3 4 -3 0 1 -1 0 -3 -4 0 -3 -3 -2 0 -1 -4 -3 -3 4 1 -1 -4 -4
+Z -1 0 0 1 -3 3 4 -2 0 -3 -3 1 -1 -3 -1 0 -1 -3 -2 -2 1 4 -1 -4 -4
+X 0 -1 -1 -1 -2 -1 -1 -1 -1 -1 -1 -1 -1 -1 -2 0 0 -2 -1 -1 -1 -1 -1 -4 -4
+ -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 1 1
+* -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 1 1
+#
+# A R N D C Q E G H I L K M F P S T W Y V B Z X *
--- /dev/null
+ScoreMatrix BLOSUM80
+ARNDCQEGHILKMFPSTWYVBJZX*
+#
+# Source: https://www.ncbi.nlm.nih.gov/IEB/ToolBox/C_DOC/lxr/source/data/BLOSUM80
+#
+# ** THIS IS A SUGGESTED FILE, NOT VALIDATED **
+# Please read https://www.biostars.org/p/190004/ for possible alternatives!
+#
+# The first line declares a ScoreMatrix with the name BLOSUM80
+# The second line gives the symbols for which scores are held in the matrix
+# These may include a space (but not as the first or last character)
+#
+# Scores are not symbol case sensitive, unless column(s) are provided for lower case characters
+# The 'guide symbol' at the start of each row of score values is optional
+#
+# Comment header line with symbols is provided as a guide
+# Values may be integer or floating point, delimited by tab, space, comma or combinations
+#
+# A R N D C Q E G H I L K M F P S T W Y V B J Z X *
+A 5 -2 -2 -2 -1 -1 -1 0 -2 -2 -2 -1 -1 -3 -1 1 0 -3 -2 0 -2 -2 -1 -1 -6
+R -2 6 -1 -2 -4 1 -1 -3 0 -3 -3 2 -2 -4 -2 -1 -1 -4 -3 -3 -1 -3 0 -1 -6
+N -2 -1 6 1 -3 0 -1 -1 0 -4 -4 0 -3 -4 -3 0 0 -4 -3 -4 5 -4 0 -1 -6
+D -2 -2 1 6 -4 -1 1 -2 -2 -4 -5 -1 -4 -4 -2 -1 -1 -6 -4 -4 5 -5 1 -1 -6
+C -1 -4 -3 -4 9 -4 -5 -4 -4 -2 -2 -4 -2 -3 -4 -2 -1 -3 -3 -1 -4 -2 -4 -1 -6
+Q -1 1 0 -1 -4 6 2 -2 1 -3 -3 1 0 -4 -2 0 -1 -3 -2 -3 0 -3 4 -1 -6
+E -1 -1 -1 1 -5 2 6 -3 0 -4 -4 1 -2 -4 -2 0 -1 -4 -3 -3 1 -4 5 -1 -6
+G 0 -3 -1 -2 -4 -2 -3 6 -3 -5 -4 -2 -4 -4 -3 -1 -2 -4 -4 -4 -1 -5 -3 -1 -6
+H -2 0 0 -2 -4 1 0 -3 8 -4 -3 -1 -2 -2 -3 -1 -2 -3 2 -4 -1 -4 0 -1 -6
+I -2 -3 -4 -4 -2 -3 -4 -5 -4 5 1 -3 1 -1 -4 -3 -1 -3 -2 3 -4 3 -4 -1 -6
+L -2 -3 -4 -5 -2 -3 -4 -4 -3 1 4 -3 2 0 -3 -3 -2 -2 -2 1 -4 3 -3 -1 -6
+K -1 2 0 -1 -4 1 1 -2 -1 -3 -3 5 -2 -4 -1 -1 -1 -4 -3 -3 -1 -3 1 -1 -6
+M -1 -2 -3 -4 -2 0 -2 -4 -2 1 2 -2 6 0 -3 -2 -1 -2 -2 1 -3 2 -1 -1 -6
+F -3 -4 -4 -4 -3 -4 -4 -4 -2 -1 0 -4 0 6 -4 -3 -2 0 3 -1 -4 0 -4 -1 -6
+P -1 -2 -3 -2 -4 -2 -2 -3 -3 -4 -3 -1 -3 -4 8 -1 -2 -5 -4 -3 -2 -4 -2 -1 -6
+S 1 -1 0 -1 -2 0 0 -1 -1 -3 -3 -1 -2 -3 -1 5 1 -4 -2 -2 0 -3 0 -1 -6
+T 0 -1 0 -1 -1 -1 -1 -2 -2 -1 -2 -1 -1 -2 -2 1 5 -4 -2 0 -1 -1 -1 -1 -6
+W -3 -4 -4 -6 -3 -3 -4 -4 -3 -3 -2 -4 -2 0 -5 -4 -4 11 2 -3 -5 -3 -3 -1 -6
+Y -2 -3 -3 -4 -3 -2 -3 -4 2 -2 -2 -3 -2 3 -4 -2 -2 2 7 -2 -3 -2 -3 -1 -6
+V 0 -3 -4 -4 -1 -3 -3 -4 -4 3 1 -3 1 -1 -3 -2 0 -3 -2 4 -4 2 -3 -1 -6
+B -2 -1 5 5 -4 0 1 -1 -1 -4 -4 -1 -3 -4 -2 0 -1 -5 -3 -4 5 -4 0 -1 -6
+J -2 -3 -4 -5 -2 -3 -4 -5 -4 3 3 -3 2 0 -4 -3 -1 -3 -2 2 -4 3 -3 -1 -6
+Z -1 0 0 1 -4 4 5 -3 0 -4 -3 1 -1 -4 -2 0 -1 -3 -3 -3 0 -3 5 -1 -6
+X -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -6
+* -6 -6 -6 -6 -6 -6 -6 -6 -6 -6 -6 -6 -6 -6 -6 -6 -6 -6 -6 -6 -6 -6 -6 -6 1
+#
+# A R N D C Q E G H I L K M F P S T W Y V B J Z X *
--- /dev/null
+ScoreMatrix DNA
+ACGTUIXRYN -
+#
+# A DNA substitution matrix.
+# This is an ad-hoc matrix which, in addition to penalising mutations between the common
+# nucleotides (ACGT), includes T/U equivalence in order to allow both DNA and/or RNA.
+# In addition, it encodes weak equivalence between R and Y with AG and CTU, respectively,
+# and N is allowed to match any other base weakly.
+# This matrix also includes I (Inosine) and X (Xanthine), but encodes them to weakly match
+# any of (ACGTU), and unfavourably match each other.
+#
+# The first line declares a ScoreMatrix with the name DNA (shown in menus)
+# The second line gives the symbols for which scores are held in the matrix
+# These may include a space (but not as the first or last character)
+# Scores are not case sensitive, unless column(s) are provided for lower case characters
+#
+#
+# Comment line with symbols is provided as a guide
+# Values may be integer or floating point, delimited by tab, space, comma or combinations
+#
+# A C G T U I X R Y N -
+#
+ 10 -8 -8 -8 -8 1 1 1 -8 1 1 1
+ -8 10 -8 -8 -8 1 1 -8 1 1 1 1
+ -8 -8 10 -8 -8 1 1 1 -8 1 1 1
+ -8 -8 -8 10 10 1 1 -8 1 1 1 1
+ -8 -8 -8 10 10 1 1 -8 1 1 1 1
+ 1 1 1 1 1 10 0 0 0 1 1 1
+ 1 1 1 1 1 0 10 0 0 1 1 1
+ 1 -8 1 -8 -8 0 0 10 -8 1 1 1
+ -8 1 -8 1 1 0 0 -8 10 1 1 1
+ 1 1 1 1 1 1 1 1 1 10 1 1
+ 1 1 1 1 1 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1 1 1 1 1 1
+#
+# A C G T U I X R Y N -
--- /dev/null
+ScoreMatrix PAM250
+ARNDCQEGHILKMFPSTWYVBZX *
+#
+# The PAM250 substitution matrix
+# The first line declares a ScoreMatrix with the name PAM250 (shown in menus)
+# The second line gives the symbols for which scores are held in the matrix
+# These may include a space (but not as the first or last character)
+# Scores are not case sensitive, unless column(s) are provided for lower case characters
+#
+#
+# Comment line with symbols is provided as a guide
+# Values may be integer or floating point, delimited by tab, space, comma or combinations
+#
+# A R N D C Q E G H I L K M F P S T W Y V B Z X *
+#
+ 2 -2 0 0 -2 0 0 1 -1 -1 -2 -1 -1 -3 1 1 1 -6 -3 0 0 0 0 -8 -8
+ -2 6 0 -1 -4 1 -1 -3 2 -2 -3 3 0 -4 0 0 -1 2 -4 -2 -1 0 -1 -8 -8
+ 0 0 2 2 -4 1 1 0 2 -2 -3 1 -2 -3 0 1 0 -4 -2 -2 2 1 0 -8 -8
+ 0 -1 2 4 -5 2 3 1 1 -2 -4 0 -3 -6 -1 0 0 -7 -4 -2 3 3 -1 -8 -8
+ -2 -4 -4 -5 12 -5 -5 -3 -3 -2 -6 -5 -5 -4 -3 0 -2 -8 0 -2 -4 -5 -3 -8 -8
+ 0 1 1 2 -5 4 2 -1 3 -2 -2 1 -1 -5 0 -1 -1 -5 -4 -2 1 3 -1 -8 -8
+ 0 -1 1 3 -5 2 4 0 1 -2 -3 0 -2 -5 -1 0 0 -7 -4 -2 3 3 -1 -8 -8
+ 1 -3 0 1 -3 -1 0 5 -2 -3 -4 -2 -3 -5 0 1 0 -7 -5 -1 0 0 -1 -8 -8
+ -1 2 2 1 -3 3 1 -2 6 -2 -2 0 -2 -2 0 -1 -1 -3 0 -2 1 2 -1 -8 -8
+ -1 -2 -2 -2 -2 -2 -2 -3 -2 5 2 -2 2 1 -2 -1 0 -5 -1 4 -2 -2 -1 -8 -8
+ -2 -3 -3 -4 -6 -2 -3 -4 -2 2 6 -3 4 2 -3 -3 -2 -2 -1 2 -3 -3 -1 -8 -8
+ -1 3 1 0 -5 1 0 -2 0 -2 -3 5 0 -5 -1 0 0 -3 -4 -2 1 0 -1 -8 -8
+ -1 0 -2 -3 -5 -1 -2 -3 -2 2 4 0 6 0 -2 -2 -1 -4 -2 2 -2 -2 -1 -8 -8
+ -3 -4 -3 -6 -4 -5 -5 -5 -2 1 2 -5 0 9 -5 -3 -3 0 7 -1 -4 -5 -2 -8 -8
+ 1 0 0 -1 -3 0 -1 0 0 -2 -3 -1 -2 -5 6 1 0 -6 -5 -1 -1 0 -1 -8 -8
+ 1 0 1 0 0 -1 0 1 -1 -1 -3 0 -2 -3 1 2 1 -2 -3 -1 0 0 0 -8 -8
+ 1 -1 0 0 -2 -1 0 0 -1 0 -2 0 -1 -3 0 1 3 -5 -3 0 0 -1 0 -8 -8
+ -6 2 -4 -7 -8 -5 -7 -7 -3 -5 -2 -3 -4 0 -6 -2 -5 17 0 -6 -5 -6 -4 -8 -8
+ -3 -4 -2 -4 0 -4 -4 -5 0 -1 -1 -4 -2 7 -5 -3 -3 0 10 -2 -3 -4 -2 -8 -8
+ 0 -2 -2 -2 -2 -2 -2 -1 -2 4 2 -2 2 -1 -1 -1 0 -6 -2 4 -2 -2 -1 -8 -8
+ 0 -1 2 3 -4 1 3 0 1 -2 -3 1 -2 -4 -1 0 0 -5 -3 -2 3 2 -1 -8 -8
+ 0 0 1 3 -5 3 3 0 2 -2 -3 0 -2 -5 0 0 -1 -6 -4 -2 2 3 -1 -8 -8
+ 0 -1 0 -1 -3 -1 -1 -1 -1 -1 -1 -1 -1 -2 -1 0 0 -4 -2 -1 -1 -1 -1 -8 -8
+ -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 1 1
+ -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 -8 1 1
+#
+# A R N D C Q E G H I L K M F P S T W Y V B Z X *
--- /dev/null
+ScoreMatrix Identity (SeqSpace)
+ARNDCQEGHILKMFPSTWYVBZX
+#
+# The identity substitution matrix, that gives the SeqSpace PCA calculation as in Jalview 2.10.1
+#
+#
+# A R N D C Q E G H I L K M F P S T W Y V B Z X
+#
+A 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+R 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+N 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+D 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+C 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+Q 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+E 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+G 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+H 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+I 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+L 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+K 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
+M 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
+F 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
+P 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
+S 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
+T 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
+W 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
+Y 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
+V 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
+B 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
+Z 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
+X 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
colourBySequence();
- int max = -10;
+ float max = -10;
int maxchain = -1;
int pdbstart = 0;
int pdbend = 0;
colourBySequence();
- int max = -10;
+ float max = -10;
int maxchain = -1;
int pdbstart = 0;
int pdbend = 0;
*/
package jalview.analysis;
+import jalview.analysis.scoremodels.ScoreMatrix;
+import jalview.analysis.scoremodels.ScoreModels;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Mapping;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
-import jalview.schemes.ResidueProperties;
-import jalview.schemes.ScoreMatrix;
import jalview.util.Comparison;
import jalview.util.Format;
import jalview.util.MapList;
private static final String NEWLINE = System.lineSeparator();
- static String[] dna = { "A", "C", "G", "T", "-" };
+ float[][] score;
- // "C", "T", "A", "G", "-"};
- static String[] pep = { "A", "R", "N", "D", "C", "Q", "E", "G", "H", "I",
- "L", "K", "M", "F", "P", "S", "T", "W", "Y", "V", "B", "Z", "X", "-" };
+ float[][] E;
- int[][] score;
-
- int[][] E;
-
- int[][] F;
+ float[][] F;
int[][] traceback;
int count;
/** DOCUMENT ME!! */
- public int maxscore;
+ public float maxscore;
float pid;
int gapExtend = 20;
- int[][] lookup = ResidueProperties.getBLOSUM62();
+ float[][] lookup;
- String[] intToStr = pep;
-
- int defInt = 23;
+ int gapIndex = 23;
StringBuffer output = new StringBuffer();
- String type;
+ String type; // AlignSeq.PEP or AlignSeq.DNA
- private int[] charToInt;
+ private ScoreMatrix scoreModel;
/**
* Creates a new AlignSeq object.
*
- * @param s1
- * DOCUMENT ME!
- * @param s2
- * DOCUMENT ME!
- * @param type
- * DOCUMENT ME!
+ * @param s1 first sequence for alignment
+ * @param s2 second sequence for alignment
+ * @param type molecule type, either AlignSeq.PEP or AlignSeq.DNA
*/
public AlignSeq(SequenceI s1, SequenceI s2, String type)
{
- SeqInit(s1, s1.getSequenceAsString(), s2, s2.getSequenceAsString(),
+ seqInit(s1, s1.getSequenceAsString(), s2, s2.getSequenceAsString(),
type);
}
public AlignSeq(SequenceI s1, String string1, SequenceI s2,
String string2, String type)
{
- SeqInit(s1, string1.toUpperCase(), s2, string2.toUpperCase(), type);
+ seqInit(s1, string1.toUpperCase(), s2, string2.toUpperCase(), type);
}
/**
*
* @return DOCUMENT ME!
*/
- public int getMaxScore()
+ public float getMaxScore()
{
return maxscore;
}
}
/**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public SequenceI getS1()
- {
- return s1;
- }
-
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public SequenceI getS2()
- {
- return s2;
- }
-
- /**
*
* @return aligned instance of Seq 1
*/
* @param type
* DNA or PEPTIDE
*/
- public void SeqInit(SequenceI s1, String string1, SequenceI s2,
+ public void seqInit(SequenceI s1, String string1, SequenceI s2,
String string2, String type)
{
this.s1 = s1;
this.s2 = s2;
setDefaultParams(type);
- SeqInit(string1, string2);
- }
-
- /**
- * Construct score matrix for sequences with custom substitution matrix
- *
- * @param s1
- * - sequence 1
- * @param string1
- * - string to use for s1
- * @param s2
- * - sequence 2
- * @param string2
- * - string to use for s2
- * @param scoreMatrix
- * - substitution matrix to use for alignment
- */
- public void SeqInit(SequenceI s1, String string1, SequenceI s2,
- String string2, ScoreMatrix scoreMatrix)
- {
- this.s1 = s1;
- this.s2 = s2;
- setType(scoreMatrix.isDNA() ? AlignSeq.DNA : AlignSeq.PEP);
- lookup = scoreMatrix.getMatrix();
+ seqInit(string1, string2);
}
/**
* @param string1
* @param string2
*/
- private void SeqInit(String string1, String string2)
+ private void seqInit(String string1, String string2)
{
s1str = extractGaps(jalview.util.Comparison.GapChars, string1);
s2str = extractGaps(jalview.util.Comparison.GapChars, string2);
return;
}
- // System.out.println("lookuip " + rt.freeMemory() + " "+ rt.totalMemory());
seq1 = new int[s1str.length()];
- // System.out.println("seq1 " + rt.freeMemory() +" " + rt.totalMemory());
seq2 = new int[s2str.length()];
- // System.out.println("seq2 " + rt.freeMemory() + " " + rt.totalMemory());
- score = new int[s1str.length()][s2str.length()];
+ score = new float[s1str.length()][s2str.length()];
- // System.out.println("score " + rt.freeMemory() + " " + rt.totalMemory());
- E = new int[s1str.length()][s2str.length()];
+ E = new float[s1str.length()][s2str.length()];
- // System.out.println("E " + rt.freeMemory() + " " + rt.totalMemory());
- F = new int[s1str.length()][s2str.length()];
+ F = new float[s1str.length()][s2str.length()];
traceback = new int[s1str.length()][s2str.length()];
- // System.out.println("F " + rt.freeMemory() + " " + rt.totalMemory());
- seq1 = stringToInt(s1str, type);
-
- // System.out.println("seq1 " + rt.freeMemory() + " " + rt.totalMemory());
- seq2 = stringToInt(s2str, type);
-
- // System.out.println("Seq2 " + rt.freeMemory() + " " + rt.totalMemory());
- // long tstart = System.currentTimeMillis();
- // calcScoreMatrix();
- // long tend = System.currentTimeMillis();
- // System.out.println("Time take to calculate score matrix = " +
- // (tend-tstart) + " ms");
- // printScoreMatrix(score);
- // System.out.println();
- // printScoreMatrix(traceback);
- // System.out.println();
- // printScoreMatrix(E);
- // System.out.println();
- // /printScoreMatrix(F);
- // System.out.println();
- // tstart = System.currentTimeMillis();
- // traceAlignment();
- // tend = System.currentTimeMillis();
- // System.out.println("Time take to traceback alignment = " + (tend-tstart)
- // + " ms");
- }
-
- private void setDefaultParams(String type)
- {
- setType(type);
+ seq1 = indexEncode(s1str);
- if (type.equals(AlignSeq.PEP))
- {
- lookup = ResidueProperties.getDefaultPeptideMatrix();
- }
- else if (type.equals(AlignSeq.DNA))
- {
- lookup = ResidueProperties.getDefaultDnaMatrix();
- }
+ seq2 = indexEncode(s2str);
}
- private void setType(String type2)
+ private void setDefaultParams(String moleculeType)
{
- this.type = type2;
- if (type.equals(AlignSeq.PEP))
- {
- intToStr = pep;
- charToInt = ResidueProperties.aaIndex;
- defInt = ResidueProperties.maxProteinIndex;
- }
- else if (type.equals(AlignSeq.DNA))
- {
- intToStr = dna;
- charToInt = ResidueProperties.nucleotideIndex;
- defInt = ResidueProperties.maxNucleotideIndex;
- }
- else
+ if (!PEP.equals(moleculeType) && !DNA.equals(moleculeType))
{
output.append("Wrong type = dna or pep only");
throw new Error(MessageManager.formatMessage(
- "error.unknown_type_dna_or_pep", new String[] { type2 }));
+ "error.unknown_type_dna_or_pep",
+ new String[] { moleculeType }));
}
+
+ type = moleculeType;
+ scoreModel = ScoreModels.getInstance().getDefaultModel(
+ PEP.equals(type));
+ lookup = scoreModel.getMatrix();
+ gapIndex = scoreModel.getMatrixIndex(' ');
}
/**
public void traceAlignment()
{
// Find the maximum score along the rhs or bottom row
- int max = -9999;
+ float max = -Float.MAX_VALUE;
for (int i = 0; i < seq1.length; i++)
{
aseq1 = new int[seq1.length + seq2.length];
aseq2 = new int[seq1.length + seq2.length];
+ StringBuilder sb1 = new StringBuilder(aseq1.length);
+ StringBuilder sb2 = new StringBuilder(aseq2.length);
+
count = (seq1.length + seq2.length) - 1;
- while ((i > 0) && (j > 0))
+ while (i > 0 && j > 0)
{
- if ((aseq1[count] != defInt) && (i >= 0))
- {
- aseq1[count] = seq1[i];
- astr1 = s1str.charAt(i) + astr1;
- }
-
- if ((aseq2[count] != defInt) && (j > 0))
- {
- aseq2[count] = seq2[j];
- astr2 = s2str.charAt(j) + astr2;
- }
+ aseq1[count] = seq1[i];
+ sb1.append(s1str.charAt(i));
+ aseq2[count] = seq2[j];
+ sb2.append(s2str.charAt(j));
trace = findTrace(i, j);
else if (trace == 1)
{
j--;
- aseq1[count] = defInt;
- astr1 = "-" + astr1.substring(1);
+ aseq1[count] = gapIndex;
+ sb1.replace(sb1.length() - 1, sb1.length(), "-");
}
else if (trace == -1)
{
i--;
- aseq2[count] = defInt;
- astr2 = "-" + astr2.substring(1);
+ aseq2[count] = gapIndex;
+ sb2.replace(sb2.length() - 1, sb2.length(), "-");
}
count--;
seq1start = i + 1;
seq2start = j + 1;
- if (aseq1[count] != defInt)
+ if (aseq1[count] != gapIndex)
{
aseq1[count] = seq1[i];
- astr1 = s1str.charAt(i) + astr1;
+ sb1.append(s1str.charAt(i));
}
- if (aseq2[count] != defInt)
+ if (aseq2[count] != gapIndex)
{
aseq2[count] = seq2[j];
- astr2 = s2str.charAt(j) + astr2;
+ sb2.append(s2str.charAt(j));
}
+
+ /*
+ * we built the character strings backwards, so now
+ * reverse them to convert to sequence strings
+ */
+ astr1 = sb1.reverse().toString();
+ astr2 = sb2.reverse().toString();
}
/**
.append(String.valueOf(s2str.length())).append(")")
.append(NEWLINE).append(NEWLINE);
+ ScoreMatrix pam250 = ScoreModels.getInstance().getPam250();
+
for (int j = 0; j < nochunks; j++)
{
// Print the first aligned sequence
output.append(NEWLINE);
output.append(new Format("%" + (maxid) + "s").form(" ")).append(" ");
- // Print out the matching chars
+ /*
+ * Print out the match symbols:
+ * | for exact match (ignoring case)
+ * . if PAM250 score is positive
+ * else a space
+ */
for (int i = 0; i < len; i++)
{
if ((i + (j * len)) < astr1.length())
{
- boolean sameChar = Comparison.isSameResidue(
- astr1.charAt(i + (j * len)), astr2.charAt(i + (j * len)),
- false);
- if (sameChar
- && !jalview.util.Comparison.isGap(astr1.charAt(i
- + (j * len))))
+ char c1 = astr1.charAt(i + (j * len));
+ char c2 = astr2.charAt(i + (j * len));
+ boolean sameChar = Comparison.isSameResidue(c1, c2, false);
+ if (sameChar && !Comparison.isGap(c1))
{
pid++;
output.append("|");
}
else if (type.equals("pep"))
{
- if (ResidueProperties.getPAM250(astr1.charAt(i + (j * len)),
- astr2.charAt(i + (j * len))) > 0)
+ if (pam250.getPairwiseScore(c1, c2) > 0)
{
output.append(".");
}
/**
* DOCUMENT ME!
*
- * @param mat
- * DOCUMENT ME!
- */
- public void printScoreMatrix(int[][] mat)
- {
- int n = seq1.length;
- int m = seq2.length;
-
- for (int i = 0; i < n; i++)
- {
- // Print the top sequence
- if (i == 0)
- {
- Format.print(System.out, "%8s", s2str.substring(0, 1));
-
- for (int jj = 1; jj < m; jj++)
- {
- Format.print(System.out, "%5s", s2str.substring(jj, jj + 1));
- }
-
- System.out.println();
- }
-
- for (int j = 0; j < m; j++)
- {
- if (j == 0)
- {
- Format.print(System.out, "%3s", s1str.substring(i, i + 1));
- }
-
- Format.print(System.out, "%3d ", mat[i][j] / 10);
- }
-
- System.out.println();
- }
- }
-
- /**
- * DOCUMENT ME!
- *
* @param i
* DOCUMENT ME!
* @param j
public int findTrace(int i, int j)
{
int t = 0;
- int max = score[i - 1][j - 1] + (lookup[seq1[i]][seq2[j]] * 10);
+ float max = score[i - 1][j - 1] + (lookup[seq1[i]][seq2[j]] * 10);
if (F[i][j] > max)
{
/**
* DOCUMENT ME!
*
- * @param i1
+ * @param f1
* DOCUMENT ME!
- * @param i2
+ * @param f2
* DOCUMENT ME!
- * @param i3
+ * @param f3
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
- public int max(int i1, int i2, int i3)
+ private static float max(float f1, float f2, float f3)
{
- int max = i1;
+ float max = f1;
- if (i2 > i1)
+ if (f2 > f1)
{
- max = i2;
+ max = f2;
}
- if (i3 > max)
+ if (f3 > max)
{
- max = i3;
+ max = f3;
}
return max;
/**
* DOCUMENT ME!
*
- * @param i1
+ * @param f1
* DOCUMENT ME!
- * @param i2
+ * @param f2
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
- public int max(int i1, int i2)
+ private static float max(float f1, float f2)
{
- int max = i1;
+ float max = f1;
- if (i2 > i1)
+ if (f2 > f1)
{
- max = i2;
+ max = f2;
}
return max;
}
/**
- * DOCUMENT ME!
+ * Converts the character string to an array of integers which are the
+ * corresponding indices to the characters in the score matrix
*
* @param s
- * DOCUMENT ME!
- * @param type
- * DOCUMENT ME!
*
- * @return DOCUMENT ME!
+ * @return
*/
- public int[] stringToInt(String s, String type)
+ int[] indexEncode(String s)
{
- int[] seq1 = new int[s.length()];
+ int[] encoded = new int[s.length()];
for (int i = 0; i < s.length(); i++)
{
- // String ss = s.substring(i, i + 1).toUpperCase();
char c = s.charAt(i);
- if ('a' <= c && c <= 'z')
- {
- // TO UPPERCASE !!!
- c -= ('a' - 'A');
- }
-
- try
- {
- seq1[i] = charToInt[c]; // set accordingly from setType
- if (seq1[i] < 0 || seq1[i] > defInt) // set from setType: 23 for
- // peptides, or 4 for NA.
- {
- seq1[i] = defInt;
- }
-
- } catch (Exception e)
- {
- seq1[i] = defInt;
- }
+ encoded[i] = scoreModel.getMatrixIndex(c);
}
- return seq1;
+ return encoded;
}
/**
{
SequenceI bestm = null;
AlignSeq bestaseq = null;
- int bestscore = 0;
+ float bestscore = 0;
for (SequenceI msq : al.getSequences())
{
AlignSeq aseq = doGlobalNWAlignment(msq, sq, dnaOrProtein);
*/
package jalview.analysis;
+import jalview.analysis.scoremodels.ScoreMatrix;
+import jalview.analysis.scoremodels.ScoreModels;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Annotation;
import jalview.datamodel.ResidueCount;
}
/**
- * Translate sequence i into a numerical representation and store it in the
- * i'th position of the seqNums array.
+ * Translate sequence i into score matrix indices and store it in the i'th
+ * position of the seqNums array.
*
* @param i
+ * @param sm
*/
- private void calcSeqNum(int i)
+ private void calcSeqNum(int i, ScoreMatrix sm)
{
- String sq = null; // for dumb jbuilder not-inited exception warning
- int[] sqnum = null;
-
+ int gapIndex = sm.getMatrixIndex(' ');
int sSize = sequences.length;
if ((i > -1) && (i < sSize))
{
- sq = sequences[i].getSequenceAsString();
+ String sq = sequences[i].getSequenceAsString();
if (seqNums.size() <= i)
{
seqNums.addElement(new int[sq.length() + 1]);
}
+ /*
+ * the first entry in the array is the sequence's hashcode,
+ * following entries are matrix indices of sequence characters
+ */
if (sq.hashCode() != seqNums.elementAt(i)[0])
{
int j;
maxLength = len;
}
- sqnum = new int[len + 1]; // better to always make a new array -
+ int[] sqnum = new int[len + 1]; // better to always make a new array -
// sequence can change its length
sqnum[0] = sq.hashCode();
for (j = 1; j <= len; j++)
{
- sqnum[j] = jalview.schemes.ResidueProperties.aaIndex[sq
- .charAt(j - 1)];
+ // sqnum[j] = ResidueProperties.aaIndex[sq.charAt(j - 1)];
+ sqnum[j] = sm.getMatrixIndex(sq.charAt(j - 1));
+ if (sqnum[j] == -1)
+ {
+ sqnum[j] = gapIndex;
+ }
}
seqNums.setElementAt(sqnum, i);
/**
* DOCUMENT ME!
+ *
+ * @param sm
*/
- private void percentIdentity2()
+ private void percentIdentity(ScoreMatrix sm)
{
seqNums = new Vector<int[]>();
- // calcSeqNum(s);
int i = 0, iSize = sequences.length;
// Do we need to calculate this again?
for (i = 0; i < iSize; i++)
{
- calcSeqNum(i);
+ calcSeqNum(i, sm);
}
+ int gapIndex = sm.getMatrixIndex(' ');
+
if ((cons2 == null) || seqNumsChanged)
{
+ // FIXME remove magic number 24 without changing calc
+ // sm.getSize() returns 25 so doesn't quite do it...
cons2 = new int[maxLength][24];
- // Initialize the array
- for (int j = 0; j < 24; j++)
- {
- for (i = 0; i < maxLength; i++)
- {
- cons2[i][j] = 0;
- }
- }
-
- int[] sqnum;
int j = 0;
while (j < sequences.length)
{
- sqnum = seqNums.elementAt(j);
+ int[] sqnum = seqNums.elementAt(j);
for (i = 1; i < sqnum.length; i++)
{
for (i = sqnum.length - 1; i < maxLength; i++)
{
- cons2[i][23]++; // gap count
+ cons2[i][gapIndex]++; // gap count
}
-
j++;
}
-
- // unnecessary ?
-
- /*
- * for (int i=start; i <= end; i++) { int max = -1000; int maxi = -1; int
- * maxj = -1;
- *
- * for (int j=0;j<24;j++) { if (cons2[i][j] > max) { max = cons2[i][j];
- * maxi = i; maxj = j; } } }
- */
}
}
{
quality = new Vector<Double>();
- double max = -10000;
- int[][] BLOSUM62 = ResidueProperties.getBLOSUM62();
+ double max = -Double.MAX_VALUE;
+ ScoreMatrix blosum62 = ScoreModels.getInstance().getBlosum62();
+ float[][] blosumScores = blosum62.getMatrix();
+ int gapIndex = blosum62.getMatrixIndex(' ');
// Loop over columns // JBPNote Profiling info
// long ts = System.currentTimeMillis();
// long te = System.currentTimeMillis();
- percentIdentity2();
+ percentIdentity(blosum62);
int size = seqNums.size();
int[] lengths = new int[size];
lengths[l] = seqNums.elementAt(l).length - 1;
}
+ // todo ? remove '*' (unused?) from score matrix and
+ // use getSize() here instead of getSize() - 1 ??
+ final int symbolCount = blosum62.getSize() - 1; // 24;
+
for (j = startRes; j <= endRes; j++)
{
bigtot = 0;
// First Xr = depends on column only
- x = new double[24];
+ x = new double[symbolCount];
- for (ii = 0; ii < 24; ii++)
+ for (ii = 0; ii < symbolCount; ii++)
{
x[ii] = 0;
- for (i2 = 0; i2 < 24; i2++)
+ for (i2 = 0; i2 < symbolCount; i2++)
{
- x[ii] += (((double) cons2[j][i2] * BLOSUM62[ii][i2]) + 4);
+ x[ii] += (((double) cons2[j][i2] * blosumScores[ii][i2]) + 4);
}
x[ii] /= size;
for (k = 0; k < size; k++)
{
tot = 0;
- xx = new double[24];
- seqNum = (j < lengths[k]) ? seqNums.elementAt(k)[j + 1] : 23; // Sequence,
- // or gap
- // at the
- // end
+ xx = new double[symbolCount];
+ seqNum = (j < lengths[k]) ? seqNums.elementAt(k)[j + 1] : gapIndex;
+ // Sequence, or gap at the end
// This is a loop over r
- for (i = 0; i < 23; i++)
+ for (i = 0; i < symbolCount - 1; i++)
{
sr = 0;
- sr = (double) BLOSUM62[i][seqNum] + 4;
+ sr = (double) blosumScores[i][seqNum] + 4;
// Calculate X with another loop over residues
// System.out.println("Xi " + i + " " + x[i] + " " + sr);
// Need to normalize by gaps
}
- double newmax = -10000;
+ double newmax = -Double.MAX_VALUE;
for (j = startRes; j <= endRes; j++)
{
tmp = quality.elementAt(j).doubleValue();
- tmp = ((max - tmp) * (size - cons2[j][23])) / size;
+ // tmp = ((max - tmp) * (size - cons2[j][23])) / size;
+ tmp = ((max - tmp) * (size - cons2[j][gapIndex])) / size;
// System.out.println(tmp+ " " + j);
quality.setElementAt(new Double(tmp), j);
*/
package jalview.analysis;
-import jalview.api.analysis.ScoreModelI;
+import jalview.analysis.scoremodels.ScoreModels;
+import jalview.api.analysis.DistanceModelI;
import jalview.datamodel.AlignmentView;
import jalview.datamodel.BinaryNode;
import jalview.datamodel.CigarArray;
import jalview.datamodel.SequenceI;
import jalview.datamodel.SequenceNode;
import jalview.io.NewickFile;
-import jalview.schemes.ResidueProperties;
import java.util.Enumeration;
import java.util.List;
*/
public class NJTree
{
+ /*
+ * 'methods'
+ */
+ public static final String AVERAGE_DISTANCE = "AV";
+
+ public static final String NEIGHBOUR_JOINING = "NJ";
+
+ public static final String FROM_FILE = "FromFile";
+
Vector<Cluster> cluster;
SequenceI[] sequence;
* DOCUMENT ME!
*/
public NJTree(SequenceI[] sequence, AlignmentView seqData, String type,
- String pwtype, ScoreModelI sm, int start, int end)
+ String pwtype, DistanceModelI sm, int start, int end)
{
this.sequence = sequence;
this.node = new Vector<SequenceNode>();
this.seqData = new AlignmentView(sdata, start);
}
// System.err.println("Made seqData");// dbg
- if (!(type.equals("NJ")))
+ if (!(type.equals(NEIGHBOUR_JOINING)))
{
- type = "AV";
+ type = AVERAGE_DISTANCE;
}
if (sm == null && !(pwtype.equals("PID")))
{
- if (ResidueProperties.getScoreMatrix(pwtype) == null)
+ if (ScoreModels.getInstance().forName(pwtype) == null)
{
pwtype = "BLOSUM62";
}
{
while (noClus > 2)
{
- if (type.equals("NJ"))
+ if (type.equals(NEIGHBOUR_JOINING))
{
findMinNJDistance();
}
ri = findr(i, j);
rj = findr(j, i);
- if (type.equals("NJ"))
+ if (type.equals(NEIGHBOUR_JOINING))
{
findClusterNJDistance(i, j);
}
SequenceNode tmpi = (node.elementAt(i));
SequenceNode tmpj = (node.elementAt(j));
- if (type.equals("NJ"))
+ if (type.equals(NEIGHBOUR_JOINING))
{
findNewNJDistances(tmpi, tmpj, dist);
}
*
* @return similarity matrix used to compute tree
*/
- public float[][] findDistances(ScoreModelI _pwmatrix)
+ public float[][] findDistances(DistanceModelI _pwmatrix)
{
float[][] dist = new float[noseqs][noseqs];
if (_pwmatrix == null)
{
// Resolve substitution model
- _pwmatrix = ResidueProperties.getScoreModel(pwtype);
+ _pwmatrix = ScoreModels.getInstance().forName(pwtype);
if (_pwmatrix == null)
{
- _pwmatrix = ResidueProperties.getScoreMatrix("BLOSUM62");
+ _pwmatrix = ScoreModels.getInstance().forName("BLOSUM62");
}
}
dist = _pwmatrix.findDistances(seqData);
*/
package jalview.analysis;
+import jalview.analysis.scoremodels.PairwiseDistanceModel;
+import jalview.analysis.scoremodels.ScoreMatrix;
+import jalview.analysis.scoremodels.ScoreModels;
import jalview.math.MatrixI;
-import jalview.schemes.ResidueProperties;
-import jalview.schemes.ScoreMatrix;
import java.io.PrintStream;
String sm = s_m;
if (sm != null)
{
- scoreMatrix = ResidueProperties.getScoreMatrix(sm);
+ scoreMatrix = (ScoreMatrix) ((PairwiseDistanceModel) ScoreModels
+ .getInstance()
+ .forName(sm)).getScoreModel();
}
if (scoreMatrix == null)
{
// either we were given a non-existent score matrix or a scoremodel that
// isn't based on a pairwise symbol score matrix
- scoreMatrix = ResidueProperties
- .getScoreMatrix(sm = (nucleotides ? "DNA" : "BLOSUM62"));
+ scoreMatrix = ScoreModels.getInstance().getDefaultModel(!nucleotides);
}
details.append("PCA calculation using " + sm
+ " sequence similarity matrix\n========\n\n");
*/
package jalview.analysis.scoremodels;
-import jalview.api.analysis.ScoreModelI;
+import jalview.api.analysis.DistanceModelI;
import jalview.api.analysis.ViewBasedAnalysisI;
import jalview.datamodel.AlignmentView;
import jalview.datamodel.SeqCigar;
import jalview.datamodel.SequenceFeature;
+import jalview.util.SetUtils;
-import java.util.ArrayList;
-import java.util.Hashtable;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
-public class FeatureScoreModel implements ScoreModelI, ViewBasedAnalysisI
+public class FeatureDistanceModel implements DistanceModelI, ViewBasedAnalysisI
{
jalview.api.FeatureRenderer fr;
return true;
}
+ /**
+ * Calculates a distance measure [i][j] between each pair of sequences as the
+ * average number of features they have but do not share. That is, find the
+ * features each sequence pair has at each column, ignore feature types they
+ * have in common, and count the rest. The totals are normalised by the number
+ * of columns processed.
+ */
@Override
public float[][] findDistances(AlignmentView seqData)
{
- int nofeats = 0;
List<String> dft = fr.getDisplayedFeatureTypes();
- nofeats = dft.size();
SeqCigar[] seqs = seqData.getSequences();
int noseqs = seqs.length;
int cpwidth = 0;// = seqData.getWidth();
float[][] distance = new float[noseqs][noseqs];
- if (nofeats == 0)
+ if (dft.isEmpty())
{
- for (float[] d : distance)
- {
- for (int i = 0; i < d.length; d[i++] = 0f)
- {
- ;
- }
- }
return distance;
}
+
// need to get real position for view position
int[] viscont = seqData.getVisibleContigs();
+
+ /*
+ * scan each column, compute and add to each distance[i, j]
+ * the number of feature types that seqi and seqj do not share
+ */
for (int vc = 0; vc < viscont.length; vc += 2)
{
-
for (int cpos = viscont[vc]; cpos <= viscont[vc + 1]; cpos++)
{
cpwidth++;
- // get visible features at cpos under view's display settings and
- // compare them
- List<Hashtable<String, SequenceFeature>> sfap = new ArrayList<Hashtable<String, SequenceFeature>>();
- for (int i = 0; i < noseqs; i++)
- {
- Hashtable<String, SequenceFeature> types = new Hashtable<String, SequenceFeature>();
- int spos = seqs[i].findPosition(cpos);
- if (spos != -1)
- {
- List<SequenceFeature> sfs = fr.findFeaturesAtRes(
- seqs[i].getRefSeq(), spos);
- for (SequenceFeature sf : sfs)
- {
- types.put(sf.getType(), sf);
- }
- }
- sfap.add(types);
- }
+
+ /*
+ * first pass: record features types in column for each sequence
+ */
+ Map<SeqCigar, Set<String>> sfap = findFeatureTypesAtColumn(
+ seqs, cpos);
+
+ /*
+ * count feature types on either i'th or j'th sequence but not both
+ * and add this 'distance' measure to the total for [i, j] for j > i
+ */
for (int i = 0; i < (noseqs - 1); i++)
{
- if (cpos == 0)
- {
- distance[i][i] = 0f;
- }
for (int j = i + 1; j < noseqs; j++)
{
- int sfcommon = 0;
- // compare the two lists of features...
- Hashtable<String, SequenceFeature> fi = sfap.get(i), fk, fj = sfap
- .get(j);
- if (fi.size() > fj.size())
- {
- fk = fj;
- }
- else
- {
- fk = fi;
- fi = fj;
- }
- for (String k : fi.keySet())
- {
- SequenceFeature sfj = fk.get(k);
- if (sfj != null)
- {
- sfcommon++;
- }
- }
- distance[i][j] += (fi.size() + fk.size() - 2f * sfcommon);
- distance[j][i] += distance[i][j];
+ int seqDistance = SetUtils.countDisjunction(sfap.get(seqs[i]),
+ sfap.get(seqs[j]));
+ distance[i][j] += seqDistance;
}
}
}
}
+
+ /*
+ * normalise the distance scores (summed over columns) by the
+ * number of visible columns used in the calculation
+ */
for (int i = 0; i < noseqs; i++)
{
for (int j = i + 1; j < noseqs; j++)
return distance;
}
+ /**
+ * Builds and returns a list (one per SeqCigar) of visible feature types at
+ * the given column position
+ *
+ * @param seqs
+ * @param columnPosition
+ * @return
+ */
+ protected Map<SeqCigar, Set<String>> findFeatureTypesAtColumn(
+ SeqCigar[] seqs, int columnPosition)
+ {
+ Map<SeqCigar, Set<String>> sfap = new HashMap<SeqCigar, Set<String>>();
+ for (SeqCigar seq : seqs)
+ {
+ Set<String> types = new HashSet<String>();
+ int spos = seq.findPosition(columnPosition);
+ if (spos != -1)
+ {
+ List<SequenceFeature> sfs = fr.findFeaturesAtRes(seq.getRefSeq(),
+ spos);
+ for (SequenceFeature sf : sfs)
+ {
+ types.add(sf.getType());
+ }
+ }
+ sfap.put(seq, types);
+ }
+ return sfap;
+ }
+
@Override
public String getName()
{
*/
package jalview.analysis.scoremodels;
-import jalview.api.analysis.ScoreModelI;
+import jalview.api.analysis.DistanceModelI;
import jalview.datamodel.AlignmentView;
import jalview.util.Comparison;
-public class PIDScoreModel implements ScoreModelI
+public class PIDDistanceModel implements DistanceModelI
{
@Override
public float[][] findDistances(AlignmentView seqData)
{
String[] sequenceString = seqData
- .getSequenceStrings(Comparison.GapChars.charAt(0));
+ .getSequenceStrings(Comparison.GAP_SPACE);
int noseqs = sequenceString.length;
float[][] distance = new float[noseqs][noseqs];
for (int i = 0; i < (noseqs - 1); i++)
return true;
}
+ @Override
+ public String toString()
+ {
+ return "Percentage identity of sequences";
+ }
}
*/
package jalview.analysis.scoremodels;
-import jalview.api.analysis.ScoreModelI;
+import jalview.api.analysis.DistanceModelI;
import jalview.datamodel.AlignmentView;
import jalview.util.Comparison;
-public abstract class PairwiseSeqScoreModel implements ScoreModelI
+public class PairwiseDistanceModel implements DistanceModelI
{
- abstract public int getPairwiseScore(char c, char d);
+ PairwiseScoreModelI scoreModel;
+ /**
+ * Constructor given something to provide pairwise scores for residues
+ *
+ * @param sm
+ */
+ public PairwiseDistanceModel(PairwiseScoreModelI sm)
+ {
+ scoreModel = sm;
+ }
+
+ /**
+ * Returns a matrix of [i][j] values representing distances between pairs of
+ * sequences
+ */
+ @Override
public float[][] findDistances(AlignmentView seqData)
{
String[] sequenceString = seqData
- .getSequenceStrings(Comparison.GapChars.charAt(0));
+ .getSequenceStrings(Comparison.GAP_SPACE);
int noseqs = sequenceString.length;
float[][] distance = new float[noseqs][noseqs];
- int maxscore = 0;
+ /*
+ * calculate similarity scores for the upper half of the matrix
+ * as [i, j] = the sum of pairwise scores of corresponding
+ * positions of sequence[i] and sequence[j]
+ */
+ float maxscore = 0;
int end = sequenceString[0].length();
for (int i = 0; i < (noseqs - 1); i++)
{
for (int j = i; j < noseqs; j++)
{
- int score = 0;
+ float score = 0;
for (int k = 0; k < end; k++)
{
try
{
- score += getPairwiseScore(sequenceString[i].charAt(k),
+ score += scoreModel.getPairwiseScore(
+ sequenceString[i].charAt(k),
sequenceString[j].charAt(k));
} catch (Exception ex)
{
}
}
- distance[i][j] = (float) score;
+ distance[i][j] = score;
if (score > maxscore)
{
}
}
+ /*
+ * subtract similarity scores from the maximum value to
+ * convert to a distance measure; also populate the lower
+ * half of the result matrix with this value
+ */
+ // FIXME this assumes the score matrix is symmetric - it may not be?
for (int i = 0; i < (noseqs - 1); i++)
{
for (int j = i; j < noseqs; j++)
{
- distance[i][j] = (float) maxscore - distance[i][j];
+ distance[i][j] = maxscore - distance[i][j];
distance[j][i] = distance[i][j];
}
}
return distance;
}
- abstract public int[][] getMatrix();
+ @Override
+ public String getName()
+ {
+ return scoreModel.getName();
+ }
+
+ @Override
+ public boolean isDNA()
+ {
+ return scoreModel.isDNA();
+ }
+
+ @Override
+ public boolean isProtein()
+ {
+ return scoreModel.isProtein();
+ }
+
+ public PairwiseScoreModelI getScoreModel()
+ {
+ return scoreModel;
+ }
}
--- /dev/null
+package jalview.analysis.scoremodels;
+
+/**
+ * An interface that describes classes that can compute similarity (aka
+ * substitution) scores for pairs of residues
+ */
+public interface PairwiseScoreModelI
+{
+ /**
+ * Answers a similarity score between two sequence characters (for
+ * substitution of the first by the second). Typically the highest scores are
+ * for identity, and the lowest for substitution of a residue by one with very
+ * different properties.
+ *
+ * @param c
+ * @param d
+ * @return
+ */
+ abstract public float getPairwiseScore(char c, char d);
+
+ /**
+ * Returns a readable name for the model, suitable for display in menus
+ *
+ * @return
+ */
+ String getName();
+
+ /**
+ * Answers true if the model is applicable to nucleotide data
+ *
+ * @return
+ */
+ boolean isDNA();
+
+ /**
+ * Answers true if the model is applicable to peptide data
+ *
+ * @return
+ */
+ boolean isProtein();
+
+}
package jalview.analysis.scoremodels;
import jalview.analysis.AlignSeq;
-import jalview.api.analysis.ScoreModelI;
+import jalview.api.analysis.DistanceModelI;
import jalview.datamodel.AlignmentView;
import jalview.datamodel.SequenceI;
import jalview.util.Comparison;
-public class SWScoreModel implements ScoreModelI
+public class SWDistanceModel implements DistanceModelI
{
@Override
public float[][] findDistances(AlignmentView seqData)
{
SequenceI[] sequenceString = seqData.getVisibleAlignment(
- Comparison.GapChars.charAt(0)).getSequencesArray();
+ Comparison.GAP_SPACE).getSequencesArray();
int noseqs = sequenceString.length;
float[][] distance = new float[noseqs][noseqs];
as.calcScoreMatrix();
as.traceAlignment();
as.printAlignment(System.out);
- distance[i][j] = (float) as.maxscore;
+ distance[i][j] = as.maxscore;
if (max < distance[i][j])
{
return true;
}
+ @Override
public String toString()
{
return "Score between two sequences aligned with Smith Waterman with default Peptide/Nucleotide matrix";
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.analysis.scoremodels;
+
+import jalview.math.Matrix;
+import jalview.math.MatrixI;
+
+import java.util.Arrays;
+
+public class ScoreMatrix implements PairwiseScoreModelI
+{
+ public static final short UNMAPPED = (short) -1;
+
+ private static final String BAD_ASCII_ERROR = "Unexpected character %s in getPairwiseScore";
+
+ private static final int MAX_ASCII = 127;
+
+ /*
+ * the name of the model as shown in menus
+ */
+ private String name;
+
+ /*
+ * the characters that the model provides scores for
+ */
+ private char[] symbols;
+
+ /*
+ * the score matrix; both dimensions must equal the number of symbols
+ * matrix[i][j] is the substitution score for replacing symbols[i] with symbols[j]
+ */
+ private float[][] matrix;
+
+ /*
+ * quick lookup to convert from an ascii character value to the index
+ * of the corresponding symbol in the score matrix
+ */
+ private short[] symbolIndex;
+
+ /*
+ * true for Protein Score matrix, false for dna score matrix
+ */
+ private boolean peptide;
+
+ /**
+ * Constructor given a name, symbol alphabet, and matrix of scores for pairs
+ * of symbols. The matrix should be square and of the same size as the
+ * alphabet, for example 20x20 for a 20 symbol alphabet.
+ *
+ * @param name
+ * Unique, human readable name for the matrix
+ * @param alphabet
+ * the symbols to which scores apply
+ * @param matrix
+ * Pairwise scores indexed according to the symbol alphabet
+ */
+ public ScoreMatrix(String name, char[] alphabet, float[][] matrix)
+ {
+ if (alphabet.length != matrix.length)
+ {
+ throw new IllegalArgumentException(
+ "score matrix size must match alphabet size");
+ }
+ for (float[] row : matrix)
+ {
+ if (row.length != alphabet.length)
+ {
+ throw new IllegalArgumentException(
+ "score matrix size must be square");
+ }
+ }
+
+ this.matrix = matrix;
+ this.name = name;
+ this.symbols = alphabet;
+
+ symbolIndex = buildSymbolIndex(alphabet);
+
+ /*
+ * crude heuristic for now...
+ */
+ peptide = alphabet.length >= 20;
+ }
+
+ /**
+ * Returns an array A where A[i] is the position in the alphabet array of the
+ * character whose value is i. For example if the alphabet is { 'A', 'D', 'X'
+ * } then A['D'] = A[68] = 1.
+ * <p>
+ * Unmapped characters (not in the alphabet) get an index of -1.
+ * <p>
+ * Mappings are added automatically for lower case symbols (for non case
+ * sensitive scoring), unless they are explicitly present in the alphabet (are
+ * scored separately in the score matrix).
+ *
+ * @param alphabet
+ * @return
+ */
+ static short[] buildSymbolIndex(char[] alphabet)
+ {
+ short[] index = new short[MAX_ASCII + 1];
+ Arrays.fill(index, UNMAPPED);
+ short pos = 0;
+ for (char c : alphabet)
+ {
+ if (c <= MAX_ASCII)
+ {
+ index[c] = pos;
+ }
+
+ /*
+ * also map lower-case character (unless separately mapped)
+ */
+ if (c >= 'A' && c <= 'Z')
+ {
+ short lowerCase = (short) (c + ('a' - 'A'));
+ if (index[lowerCase] == UNMAPPED)
+ {
+ index[lowerCase] = pos;
+ }
+ }
+ pos++;
+ }
+ return index;
+ }
+
+ @Override
+ public String getName()
+ {
+ return name;
+ }
+
+ @Override
+ public boolean isDNA()
+ {
+ return !peptide;
+ }
+
+ @Override
+ public boolean isProtein()
+ {
+ return peptide;
+ }
+
+ /**
+ * Returns the score matrix as used in getPairwiseScore. If using this matrix
+ * directly, callers <em>must</em> also call <code>getMatrixIndex</code> in
+ * order to get the matrix index for each character (symbol).
+ *
+ * @return
+ * @see #getMatrixIndex(char)
+ */
+ public float[][] getMatrix()
+ {
+ return matrix;
+ }
+
+ /**
+ * Answers the matrix index for a given character, or -1 if unmapped in the
+ * matrix. Use this method only if using <code>getMatrix</code> in order to
+ * compute scores directly (without symbol lookup) for efficiency.
+ *
+ * @param c
+ * @return
+ * @see #getMatrix()
+ */
+ public int getMatrixIndex(char c)
+ {
+ if (c < symbolIndex.length)
+ {
+ return symbolIndex[c];
+ }
+ else
+ {
+ return UNMAPPED;
+ }
+ }
+
+ /**
+ * Returns the pairwise score for substituting c with d, or zero if c or d is
+ * an unscored or unexpected character
+ */
+ @Override
+ public float getPairwiseScore(char c, char d)
+ {
+ if (c >= symbolIndex.length)
+ {
+ System.err.println(String.format(BAD_ASCII_ERROR, c));
+ return 0;
+ }
+ if (d >= symbolIndex.length)
+ {
+ System.err.println(String.format(BAD_ASCII_ERROR, d));
+ return 0;
+ }
+
+ int cIndex = symbolIndex[c];
+ int dIndex = symbolIndex[d];
+ if (cIndex != UNMAPPED && dIndex != UNMAPPED)
+ {
+ return matrix[cIndex][dIndex];
+ }
+ return 0;
+ }
+
+ /**
+ * pretty print the matrix
+ */
+ @Override
+ public String toString()
+ {
+ return outputMatrix(false);
+ }
+
+ /**
+ * Print the score matrix, optionally formatted as html, with the alphabet symbols as column headings and at the start of each row
+ * @param html
+ * @return
+ */
+ public String outputMatrix(boolean html)
+ {
+ StringBuilder sb = new StringBuilder(512);
+
+ /*
+ * heading row with alphabet
+ */
+ if (html)
+ {
+ sb.append("<table border=\"1\">");
+ sb.append(html ? "<tr><th></th>" : "");
+ }
+ for (char sym : symbols)
+ {
+ if (html)
+ {
+ sb.append("<th> ").append(sym).append(" </th>");
+ }
+ else
+ {
+ sb.append("\t").append(sym);
+ }
+ }
+ sb.append(html ? "</tr>\n" : "\n");
+
+ /*
+ * table of scores
+ */
+ for (char c1 : symbols)
+ {
+ if (html)
+ {
+ sb.append("<tr><td>");
+ }
+ sb.append(c1).append(html ? "</td>" : "");
+ for (char c2 : symbols)
+ {
+ sb.append(html ? "<td>" : "\t")
+ .append(matrix[symbolIndex[c1]][symbolIndex[c2]])
+ .append(html ? "</td>" : "");
+ }
+ sb.append(html ? "</tr>\n" : "\n");
+ }
+ if (html)
+ {
+ sb.append("</table>");
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Answers the number of symbols coded for (also equal to the number of rows
+ * and columns of the score matrix)
+ *
+ * @return
+ */
+ public int getSize()
+ {
+ return symbols.length;
+ }
+
+ /**
+ * Computes an NxN matrix where N is the number of sequences, and entry [i, j]
+ * is sequence[i] pairwise multiplied with sequence[j], as a sum of scores
+ * computed using the current score matrix. For example
+ * <ul>
+ * <li>Sequences:</li>
+ * <li>FKL</li>
+ * <li>R-D</li>
+ * <li>QIA</li>
+ * <li>GWC</li>
+ * <li>Score matrix is BLOSUM62</li>
+ * <li>Gaps treated same as X (unknown)</li>
+ * <li>product [0, 0] = F.F + K.K + L.L = 6 + 5 + 4 = 15</li>
+ * <li>product [1, 1] = R.R + -.- + D.D = 5 + -1 + 6 = 10</li>
+ * <li>product [2, 2] = Q.Q + I.I + A.A = 5 + 4 + 4 = 13</li>
+ * <li>product [3, 3] = G.G + W.W + C.C = 6 + 11 + 9 = 26</li>
+ * <li>product[0, 1] = F.R + K.- + L.D = -3 + -1 + -3 = -8
+ * <li>and so on</li>
+ * </ul>
+ */
+ public MatrixI computePairwiseScores(String[] seqs)
+ {
+ double[][] values = new double[seqs.length][];
+ for (int row = 0; row < seqs.length; row++)
+ {
+ values[row] = new double[seqs.length];
+ for (int col = 0; col < seqs.length; col++)
+ {
+ int total = 0;
+ int width = Math.min(seqs[row].length(), seqs[col].length());
+ for (int i = 0; i < width; i++)
+ {
+ char c1 = seqs[row].charAt(i);
+ char c2 = seqs[col].charAt(i);
+ float score = getPairwiseScore(c1, c2);
+ total += score;
+ }
+ values[row][col] = total;
+ }
+ }
+ return new Matrix(values);
+ }
+}
--- /dev/null
+package jalview.analysis.scoremodels;
+
+import jalview.api.analysis.DistanceModelI;
+import jalview.io.DataSourceType;
+import jalview.io.FileParse;
+import jalview.io.ScoreMatrixFile;
+
+import java.io.IOException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * A class that can register and serve instances of ScoreModelI
+ */
+public class ScoreModels
+{
+ private final ScoreMatrix BLOSUM62;
+
+ private final ScoreMatrix PAM250;
+
+ private final ScoreMatrix DNA;
+
+ private static ScoreModels instance = new ScoreModels();
+
+ private Map<String, DistanceModelI> models;
+
+ public static ScoreModels getInstance()
+ {
+ return instance;
+ }
+
+ /**
+ * Private constructor to enforce use of singleton. Registers Jalview's
+ * "built-in" score models:
+ * <ul>
+ * <li>BLOSUM62</li>
+ * <li>PAM250</li>
+ * <li>SeqSpace (identity matrix)</li>
+ * <li>DNA</li>
+ * <li>Sequence Feature Similarity</li>
+ * <li>Percentage Identity</li>
+ * </ul>
+ */
+ private ScoreModels()
+ {
+ /*
+ * using LinkedHashMap keeps models ordered as added
+ */
+ models = new LinkedHashMap<String, DistanceModelI>();
+ BLOSUM62 = loadScoreMatrix("scoreModel/blosum62.scm");
+ PAM250 = loadScoreMatrix("scoreModel/pam250.scm");
+ loadScoreMatrix("scoreModel/seqspace.scm");
+ // drop seqspace.scm for IdentityScoreModel once JAL-2379 merged in?
+ // registerScoreModel(new IdentityScoreModel());
+ DNA = loadScoreMatrix("scoreModel/dna.scm");
+ registerScoreModel(new FeatureDistanceModel());
+ registerScoreModel(new PIDDistanceModel());
+ }
+
+ /**
+ * Tries to load a score matrix from the given resource file, and if
+ * successful, registers it.
+ *
+ * @param string
+ * @return
+ */
+ ScoreMatrix loadScoreMatrix(String resourcePath)
+ {
+ try
+ {
+ /*
+ * delegate parsing to ScoreMatrixFile
+ */
+ FileParse fp = new FileParse(resourcePath, DataSourceType.CLASSLOADER);
+ ScoreMatrix sm = new ScoreMatrixFile(fp).parseMatrix();
+ registerScoreModel(sm);
+ return sm;
+ } catch (IOException e)
+ {
+ System.err.println("Error reading " + resourcePath + ": "
+ + e.getMessage());
+ }
+ return null;
+ }
+
+ /**
+ * Registers a pairwise score model
+ *
+ * @param sm
+ */
+ public void registerScoreModel(PairwiseScoreModelI sm)
+ {
+ registerScoreModel(new PairwiseDistanceModel(sm));
+ }
+
+ /**
+ * Answers an iterable set of the registered score models. Currently these are
+ * returned in the order in which they were registered.
+ *
+ * @return
+ */
+ public Iterable<DistanceModelI> getModels()
+ {
+ return models.values();
+ }
+
+ public DistanceModelI forName(String s)
+ {
+ return models.get(s);
+ }
+
+ public void registerScoreModel(DistanceModelI sm)
+ {
+ DistanceModelI sm2 = models.get(sm.getName());
+ if (sm2 != null)
+ {
+ System.err.println("Warning: replacing score model " + sm2.getName());
+ }
+ models.put(sm.getName(), sm);
+ }
+
+ /**
+ * Returns the default peptide or nucleotide score model, currently BLOSUM62
+ * or DNA
+ *
+ * @param forPeptide
+ * @return
+ */
+ public ScoreMatrix getDefaultModel(boolean forPeptide)
+ {
+ return forPeptide ? BLOSUM62 : DNA;
+ }
+
+ public ScoreMatrix getBlosum62()
+ {
+ return BLOSUM62;
+ }
+
+ public ScoreMatrix getPam250()
+ {
+ return PAM250;
+ }
+}
* @return Sequence<->Structure mapping as int[][]
* @throws SiftsException
*/
- public StringBuffer getMappingOutput(MappingOutputPojo mop)
+ public StringBuilder getMappingOutput(MappingOutputPojo mop)
throws SiftsException;
/**
import jalview.datamodel.AlignmentView;
-public interface ScoreModelI
+/**
+ * An interface that describes classes that can compute distances between pairs
+ * of sequences in an alignment
+ */
+public interface DistanceModelI
{
float[][] findDistances(AlignmentView seqData);
String getName();
+ /**
+ * Answers true if this model is applicable for nucleotide data (so should be
+ * shown in menus in that context)
+ *
+ * @return
+ */
boolean isDNA();
+ /**
+ * Answers true if this model is applicable for peptide data (so should be
+ * shown in menus in that context)
+ *
+ * @return
+ */
boolean isProtein();
}
import jalview.analysis.AlignmentSorter;
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
+import jalview.analysis.NJTree;
import jalview.api.AlignViewControllerGuiI;
import jalview.api.AlignViewControllerI;
import jalview.api.AlignViewportI;
public void averageDistanceTreeMenuItem_actionPerformed()
{
- NewTreePanel("AV", "PID", "Average distance tree using PID");
+ NewTreePanel(NJTree.AVERAGE_DISTANCE, "PID",
+ "Average distance tree using PID");
}
public void neighbourTreeMenuItem_actionPerformed()
{
- NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");
+ NewTreePanel(NJTree.NEIGHBOUR_JOINING, "PID",
+ "Neighbour joining tree using PID");
}
protected void njTreeBlosumMenuItem_actionPerformed()
{
- NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");
+ NewTreePanel(NJTree.NEIGHBOUR_JOINING, "BL",
+ "Neighbour joining tree using BLOSUM62");
}
protected void avTreeBlosumMenuItem_actionPerformed()
{
- NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62");
+ NewTreePanel(NJTree.AVERAGE_DISTANCE, "BL",
+ "Average distance tree using BLOSUM62");
}
void NewTreePanel(String type, String pwType, String title)
package jalview.appletgui;
import jalview.analysis.NJTree;
-import jalview.api.analysis.ScoreModelI;
+import jalview.analysis.scoremodels.ScoreModels;
+import jalview.api.analysis.DistanceModelI;
import jalview.api.analysis.ViewBasedAnalysisI;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentView;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.SequenceI;
import jalview.io.NewickFile;
-import jalview.schemes.ResidueProperties;
import jalview.util.MessageManager;
import java.awt.BorderLayout;
return tree;
}
+ @Override
public void finalize() throws Throwable
{
ap = null;
this.newtree = newtree;
}
+ @Override
public void run()
{
if (newtree != null)
seqs = av.getSelectionGroup().getSequencesInOrder(
av.getAlignment());
}
- ScoreModelI sm = ResidueProperties.getScoreModel(pwtype);
+ DistanceModelI sm = ScoreModels.getInstance().forName(pwtype);
if (sm instanceof ViewBasedAnalysisI)
{
try
}
}
+ @Override
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == newickOutput)
}
}
+ @Override
public void itemStateChanged(ItemEvent evt)
{
if (evt.getSource() == fitToWindow)
*/
package jalview.datamodel;
+import jalview.analysis.scoremodels.ScoreMatrix;
import jalview.schemes.ResidueProperties;
-import jalview.schemes.ScoreMatrix;
/**
* Encode a sequence as a numeric vector using either classic residue binary
/**
* ancode using substitution matrix given in matrix
*
- * @param matrix
+ * @param smtrx
*/
- public void matrixEncode(final ScoreMatrix matrix)
+ public void matrixEncode(final ScoreMatrix smtrx)
throws InvalidSequenceTypeException
{
- if (isNa != matrix.isDNA())
+ if (isNa != smtrx.isDNA())
{
throw new InvalidSequenceTypeException("matrix "
- + matrix.getClass().getCanonicalName()
+ + smtrx.getClass().getCanonicalName()
+ " is not a valid matrix for "
+ (isNa ? "nucleotide" : "protein") + "sequences");
}
- matrixEncode(matrix.isDNA() ? ResidueProperties.nucleotideIndex
- : ResidueProperties.aaIndex, matrix.getMatrix());
+ matrixEncode(smtrx.isDNA() ? ResidueProperties.nucleotideIndex
+ : ResidueProperties.aaIndex, smtrx.getMatrix());
}
- private void matrixEncode(final int[] aaIndex, final int[][] matrix)
+ private void matrixEncode(final int[] aaIndex, final float[][] matrix)
{
int nores = initMatrixGetNoRes();
import jalview.analysis.AlignmentUtils;
import jalview.analysis.CrossRef;
import jalview.analysis.Dna;
+import jalview.analysis.NJTree;
import jalview.analysis.ParseProperties;
import jalview.analysis.SequenceIdMatcher;
import jalview.api.AlignExportSettingI;
import jalview.api.FeatureSettingsControllerI;
import jalview.api.SplitContainerI;
import jalview.api.ViewStyleI;
-import jalview.api.analysis.ScoreModelI;
+import jalview.api.analysis.DistanceModelI;
import jalview.bin.Cache;
import jalview.bin.Jalview;
import jalview.commands.CommandI;
import jalview.io.FileFormatI;
import jalview.io.FileFormats;
import jalview.io.FileLoader;
+import jalview.io.FileParse;
import jalview.io.FormatAdapter;
import jalview.io.HtmlSvgOutput;
import jalview.io.IdentifyFile;
import jalview.io.JalviewFileView;
import jalview.io.JnetAnnotationMaker;
import jalview.io.NewickFile;
+import jalview.io.ScoreMatrixFile;
import jalview.io.TCoffeeScoreFile;
import jalview.jbgui.GAlignFrame;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ColourSchemes;
import jalview.schemes.ResidueColourScheme;
-import jalview.schemes.ResidueProperties;
import jalview.schemes.TCoffeeColourScheme;
import jalview.util.MessageManager;
import jalview.viewmodel.AlignmentViewport;
setMenusFromViewport(viewport);
buildSortByAnnotationScoresMenu();
- buildTreeMenu();
+ calculateTree.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ new TreeChooser(AlignFrame.this);
+ }
+ });
buildColourMenu();
if (Desktop.desktop != null)
/**
* DOCUMENT ME!
*
- * @param e
- * DOCUMENT ME!
- */
- @Override
- public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)
- {
- newTreePanel("AV", "PID", "Average distance tree using PID");
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
- public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)
- {
- newTreePanel("NJ", "PID", "Neighbour joining tree using PID");
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
- protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)
- {
- newTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
- protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)
- {
- newTreePanel("AV", "BL", "Average distance tree using BLOSUM62");
- }
-
- /**
- * DOCUMENT ME!
- *
* @param type
* DOCUMENT ME!
* @param pwType
* call. Listeners are added to remove the menu item when the treePanel is
* closed, and adjust the tree leaf to sequence mapping when the alignment is
* modified.
- *
- * @param treePanel
- * Displayed tree window.
- * @param title
- * SortBy menu item title.
*/
@Override
- public void buildTreeMenu()
+ public void buildTreeSortMenu()
{
- calculateTree.removeAll();
- // build the calculate menu
-
- for (final String type : new String[] { "NJ", "AV" })
- {
- String treecalcnm = MessageManager.getString("label.tree_calc_"
- + type.toLowerCase());
- for (final String pwtype : ResidueProperties.scoreMatrices.keySet())
- {
- JMenuItem tm = new JMenuItem();
- ScoreModelI sm = ResidueProperties.scoreMatrices.get(pwtype);
- if (sm.isDNA() == viewport.getAlignment().isNucleotide()
- || sm.isProtein() == !viewport.getAlignment()
- .isNucleotide())
- {
- String smn = MessageManager.getStringOrReturn(
- "label.score_model_", sm.getName());
- final String title = MessageManager.formatMessage(
- "label.treecalc_title", treecalcnm, smn);
- tm.setText(title);//
- tm.addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- newTreePanel(type, pwtype, title);
- }
- });
- calculateTree.add(tm);
- }
-
- }
- }
sortByTreeMenu.removeAll();
List<Component> comps = PaintRefresher.components.get(viewport
if (nf.getTree() != null)
{
- tp = new TreePanel(alignPanel, "FromFile", title, nf, input);
+ tp = new TreePanel(alignPanel, NJTree.FROM_FILE, title, nf, input);
tp.setSize(w, h);
}
/**
- * Attempt to load a "dropped" file or URL string: First by testing whether
- * it's an Annotation file, then a JNet file, and finally a features file. If
- * all are false then the user may have dropped an alignment file onto this
- * AlignFrame.
+ * Attempt to load a "dropped" file or URL string, by testing in turn for
+ * <ul>
+ * <li>an Annotation file</li>
+ * <li>a JNet file</li>
+ * <li>a features file</li>
+ * <li>else try to interpret as an alignment file</li>
+ * </ul>
*
* @param file
* either a filename or a URL string.
{
format = new IdentifyFile().identify(file, sourceType);
}
- if (FileFormat.Jnet.equals(format))
+ if (FileFormat.ScoreMatrix == format)
+ {
+ ScoreMatrixFile sm = new ScoreMatrixFile(new FileParse(file,
+ sourceType));
+ sm.parse();
+ // todo: i18n this message
+ statusBar
+ .setText(MessageManager.formatMessage(
+ "label.successfully_loaded_matrix",
+ sm.getMatrixName()));
+ }
+ else if (FileFormat.Jnet.equals(format))
{
JPredFile predictions = new JPredFile(file, sourceType);
new JnetAnnotationMaker();
ColourMenuHelper.setColourSelected(colourMenu, schemeName);
}
+
+ public void newTreePanel(String treeType, DistanceModelI sm)
+ {
+ String scoreModelName = sm.getName();
+ final String ttl = TreePanel.getPanelTitle(treeType, scoreModelName);
+ newTreePanel(treeType, scoreModelName, ttl);
+ }
}
class PrintThread extends Thread
*/
package jalview.gui;
+import jalview.analysis.scoremodels.PairwiseDistanceModel;
+import jalview.analysis.scoremodels.ScoreModels;
+import jalview.api.analysis.DistanceModelI;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
import jalview.datamodel.SeqCigar;
import jalview.datamodel.SequenceI;
import jalview.jbgui.GPCAPanel;
-import jalview.schemes.ResidueProperties;
import jalview.util.MessageManager;
import jalview.viewmodel.AlignmentViewport;
import jalview.viewmodel.PCAModel;
protected void scoreMatrix_menuSelected()
{
scoreMatrixMenu.removeAll();
- for (final String sm : ResidueProperties.scoreMatrices.keySet())
+ for (DistanceModelI sm : ScoreModels.getInstance().getModels())
{
- if (ResidueProperties.getScoreMatrix(sm) != null)
+ if (sm instanceof PairwiseDistanceModel)
{
+ final String name = sm.getName();
// create an entry for this score matrix for use in PCA
JCheckBoxMenuItem jm = new JCheckBoxMenuItem();
jm.setText(MessageManager.getStringOrReturn("label.score_model_",
- sm));
- jm.setSelected(pcaModel.getScore_matrix().equals(sm));
- if ((ResidueProperties.scoreMatrices.get(sm).isDNA() && ResidueProperties.scoreMatrices
- .get(sm).isProtein())
- || pcaModel.isNucleotide() == ResidueProperties.scoreMatrices
- .get(sm).isDNA())
+ name));
+ jm.setSelected(pcaModel.getScore_matrix().equals(name));
+ if ((pcaModel.isNucleotide() && sm.isDNA())
+ || (!pcaModel.isNucleotide() && sm.isProtein()))
{
- final PCAPanel us = this;
jm.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- if (!pcaModel.getScore_matrix().equals(sm))
+ if (!pcaModel.getScore_matrix().equals(name))
{
- pcaModel.setScore_matrix(sm);
- Thread worker = new Thread(us);
+ pcaModel.setScore_matrix(name);
+ Thread worker = new Thread(PCAPanel.this);
worker.start();
}
}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.gui;
+
+import jalview.analysis.NJTree;
+import jalview.analysis.scoremodels.ScoreModels;
+import jalview.api.analysis.DistanceModelI;
+import jalview.util.MessageManager;
+
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JInternalFrame;
+import javax.swing.JLayeredPane;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+
+/**
+ * A dialog to allow a user to select and action Tree calculation options
+ */
+public class TreeChooser extends JPanel
+{
+ private static final Font VERDANA_11PT = new Font("Verdana", 0, 11);
+
+ AlignFrame af;
+
+ JRadioButton neighbourJoining;
+
+ JRadioButton averageDistance;
+
+ JComboBox<String> matrixNames;
+
+ private JInternalFrame frame;
+
+ private ButtonGroup treeTypes;
+
+ /**
+ * Constructor
+ *
+ * @param af
+ */
+ public TreeChooser(AlignFrame alignFrame)
+ {
+ this.af = alignFrame;
+ init();
+ }
+
+ void init()
+ {
+ frame = new JInternalFrame();
+ frame.setContentPane(this);
+ this.setBackground(Color.white);
+
+ neighbourJoining = new JRadioButton(
+ MessageManager.getString("label.tree_calc_nj"));
+ neighbourJoining.setOpaque(false);
+ averageDistance = new JRadioButton(
+ MessageManager.getString("label.tree_calc_av"));
+ treeTypes = new ButtonGroup();
+ treeTypes.add(neighbourJoining);
+ treeTypes.add(averageDistance);
+ neighbourJoining.setSelected(true);
+
+ matrixNames = new JComboBox<String>();
+ ScoreModels scoreModels = ScoreModels.getInstance();
+ for (DistanceModelI sm : scoreModels.getModels())
+ {
+ boolean nucleotide = af.getViewport().getAlignment().isNucleotide();
+ if (sm.isDNA() && nucleotide || sm.isProtein() && !nucleotide)
+ {
+ matrixNames.addItem(sm.getName());
+ }
+ }
+
+ JButton ok = new JButton(MessageManager.getString("action.ok"));
+ ok.setFont(VERDANA_11PT);
+ ok.addActionListener(new java.awt.event.ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ ok_actionPerformed(e);
+ }
+ });
+
+ JButton cancel = new JButton(MessageManager.getString("action.cancel"));
+ cancel.setFont(VERDANA_11PT);
+ cancel.addActionListener(new java.awt.event.ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ cancel_actionPerformed(e);
+ }
+ });
+
+ JPanel p1 = new JPanel();
+ p1.setOpaque(false);
+ p1.add(neighbourJoining);
+ p1.add(averageDistance);
+ this.add(p1);
+ JPanel p2 = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ p2.setOpaque(false);
+ p2.add(matrixNames, FlowLayout.LEFT);
+ this.add(p2);
+ JPanel p3 = new JPanel();
+ p3.setOpaque(false);
+ p3.add(ok);
+ p3.add(cancel);
+ this.add(p3);
+
+ Desktop.addInternalFrame(frame,
+ MessageManager.getString("label.choose_tree"),
+ 400, 200, false);
+
+ frame.setLayer(JLayeredPane.PALETTE_LAYER);
+ }
+
+ /**
+ * Open and calculate the selected tree on 'OK'
+ *
+ * @param e
+ */
+ protected void ok_actionPerformed(ActionEvent e)
+ {
+ try
+ {
+ frame.setClosed(true);
+ String treeType = neighbourJoining.isSelected() ? NJTree.NEIGHBOUR_JOINING
+ : NJTree.AVERAGE_DISTANCE;
+ DistanceModelI sm = ScoreModels.getInstance().forName(
+ matrixNames.getSelectedItem().toString());
+ af.newTreePanel(treeType, sm);
+ } catch (Exception ex)
+ {
+ }
+ }
+
+ /**
+ * Closes dialog on cancel
+ *
+ * @param e
+ */
+ protected void cancel_actionPerformed(ActionEvent e)
+ {
+ try
+ {
+ frame.setClosed(true);
+ } catch (Exception ex)
+ {
+ }
+ }
+}
import jalview.analysis.AlignmentSorter;
import jalview.analysis.NJTree;
-import jalview.api.analysis.ScoreModelI;
+import jalview.analysis.scoremodels.ScoreModels;
+import jalview.api.analysis.DistanceModelI;
import jalview.api.analysis.ViewBasedAnalysisI;
import jalview.bin.Cache;
import jalview.commands.CommandI;
import jalview.io.JalviewFileView;
import jalview.io.NewickFile;
import jalview.jbgui.GTreePanel;
-import jalview.schemes.ResidueProperties;
import jalview.util.ImageMaker;
import jalview.util.MessageManager;
import jalview.viewmodel.AlignmentViewport;
// showDistances(true);
}
- /**
- * Creates a new TreePanel object.
- *
- * @param av
- * DOCUMENT ME!
- * @param seqVector
- * DOCUMENT ME!
- * @param newtree
- * DOCUMENT ME!
- * @param type
- * DOCUMENT ME!
- * @param pwtype
- * DOCUMENT ME!
- */
- public TreePanel(AlignmentPanel ap, String type, String pwtype,
- NewickFile newtree)
- {
- super();
- initTreePanel(ap, type, pwtype, newtree, null);
- }
-
public TreePanel(AlignmentPanel av, String type, String pwtype,
NewickFile newtree, AlignmentView inputData)
{
seqs = av.getSelectionGroup().getSequencesInOrder(
av.getAlignment());
}
- ScoreModelI sm = ResidueProperties.getScoreModel(pwtype);
+ DistanceModelI sm = ScoreModels.getInstance().forName(pwtype);
if (sm instanceof ViewBasedAnalysisI)
{
try
{
CutAndPasteTransfer cap = new CutAndPasteTransfer();
- StringBuffer buffer = new StringBuffer();
-
- if (type.equals("AV"))
- {
- buffer.append("Average distance tree using ");
- }
- else
- {
- buffer.append("Neighbour joining tree using ");
- }
-
- if (pwtype.equals("BL"))
- {
- buffer.append("BLOSUM62");
- }
- else
- {
- buffer.append("PID");
- }
+ String newTitle = getPanelTitle(type, pwtype);
- jalview.io.NewickFile fout = new jalview.io.NewickFile(
- tree.getTopNode());
+ NewickFile fout = new NewickFile(tree.getTopNode());
try
{
cap.setText(fout.print(tree.isHasBootstrap(), tree.isHasDistances(),
tree.isHasRootDistance()));
- Desktop.addInternalFrame(cap, buffer.toString(), 500, 100);
+ Desktop.addInternalFrame(cap, newTitle, 500, 100);
} catch (OutOfMemoryError oom)
{
new OOMWarning("generating newick tree file", oom);
}
});
}
+
+ /**
+ * Formats a localised title for the tree panel, like
+ * <p>
+ * Neighbour Joining Using BLOSUM62
+ * <p>
+ * For a tree loaded from file, just uses the file name
+ *
+ * @param treeType
+ * NJ or AV or FromFile
+ * @param modelOrFileName
+ * @return
+ */
+ public static String getPanelTitle(String treeType, String modelOrFileName)
+ {
+ if (NJTree.FROM_FILE.equals(treeType))
+ {
+ return modelOrFileName;
+ }
+
+ /*
+ * i18n description of Neighbour Joining or Average Distance method
+ */
+ String treecalcnm = MessageManager.getString("label.tree_calc_"
+ + treeType.toLowerCase());
+
+ /*
+ * i18n description (if any) of score model used
+ */
+ String smn = MessageManager.getStringOrReturn("label.score_model_",
+ modelOrFileName);
+
+ /*
+ * put them together as <method> Using <model>
+ */
+ final String ttl = MessageManager.formatMessage("label.treecalc_title",
+ treecalcnm, smn);
+ return ttl;
+ }
}
return new FeaturesFile();
}
},
+ ScoreMatrix("Substitution matrix", "", false, false)
+ {
+ @Override
+ public AlignmentFileReaderI getReader(FileParse source)
+ throws IOException
+ {
+ return new ScoreMatrixFile(source);
+ }
+
+ @Override
+ public AlignmentFileWriterI getWriter(AlignmentI al)
+ {
+ return null;
+ }
+ },
PDB("PDB", "pdb,ent", true, false)
{
@Override
}
data = data.toUpperCase();
+ if (data.startsWith(ScoreMatrixFile.SCOREMATRIX))
+ {
+ reply = FileFormat.ScoreMatrix;
+ break;
+ }
if (data.startsWith("##GFF-VERSION"))
{
// GFF - possibly embedded in a Jalview features file!
--- /dev/null
+package jalview.io;
+
+import jalview.analysis.scoremodels.ScoreMatrix;
+import jalview.analysis.scoremodels.ScoreModels;
+import jalview.datamodel.SequenceI;
+
+import java.io.IOException;
+import java.util.StringTokenizer;
+
+/**
+ * A class that can parse a file containing a substitution matrix and register
+ * it for use in Jalview
+ *
+ * @author gmcarstairs
+ *
+ */
+// TODO modify the AlignFile / IdentifyFile pattern so that non-alignment files
+// like this are handled more naturally
+public class ScoreMatrixFile extends AlignFile implements
+ AlignmentFileReaderI
+{
+ // first non-comment line identifier - also checked in IdentifyFile
+ public static final String SCOREMATRIX = "SCOREMATRIX";
+
+ private static final String DELIMITERS = " ,\t";
+
+ private static final String COMMENT_CHAR = "#";
+
+ private String matrixName;
+
+ /**
+ * Constructor
+ *
+ * @param source
+ * @throws IOException
+ */
+ public ScoreMatrixFile(FileParse source) throws IOException
+ {
+ super(false, source);
+ }
+
+ @Override
+ public String print(SequenceI[] sqs, boolean jvsuffix)
+ {
+ return null;
+ }
+
+ /**
+ * Parses the score matrix file, and if successful registers the matrix so it
+ * will be shown in Jalview menus.
+ */
+ @Override
+ public void parse() throws IOException
+ {
+ ScoreMatrix sm = parseMatrix();
+
+ ScoreModels.getInstance().registerScoreModel(sm);
+ }
+
+ /**
+ * Parses the score matrix file and constructs a ScoreMatrix object. If an
+ * error is found in parsing, it is thrown as FileFormatException. Any
+ * warnings are written to syserr.
+ *
+ * @return
+ * @throws IOException
+ */
+ public ScoreMatrix parseMatrix() throws IOException
+ {
+ ScoreMatrix sm = null;
+ int lineNo = 0;
+ String name = null;
+ String alphabet = null;
+ float[][] scores = null;
+ int size = 0;
+ int row = 0;
+ String err = null;
+ String data;
+
+ while ((data = nextLine()) != null)
+ {
+ lineNo++;
+ data = data.trim();
+ if (data.startsWith(COMMENT_CHAR) || data.length() == 0)
+ {
+ continue;
+ }
+ if (data.toUpperCase().startsWith(SCOREMATRIX))
+ {
+ /*
+ * Parse name from ScoreMatrix <name>
+ * we allow any delimiter after ScoreMatrix then take the rest of the line
+ */
+ if (name != null)
+ {
+ System.err
+ .println("Warning: 'ScoreMatrix' repeated in file at line "
+ + lineNo);
+ }
+ StringTokenizer nameLine = new StringTokenizer(data, DELIMITERS);
+ if (nameLine.countTokens() < 2)
+ {
+ err = "Format error: expected 'ScoreMatrix <name>', found '"
+ + data + "' at line " + lineNo;
+ throw new FileFormatException(err);
+ }
+ nameLine.nextToken(); // 'ScoreMatrix'
+ name = nameLine.nextToken(); // next field
+ name = data.substring(1).substring(data.substring(1).indexOf(name));
+ continue;
+ }
+ else if (name == null)
+ {
+ err = "Format error: 'ScoreMatrix <name>' should be the first non-comment line";
+ throw new FileFormatException(err);
+ }
+
+ /*
+ * next line after ScoreMatrix should be the alphabet of scored symbols
+ */
+ if (alphabet == null)
+ {
+ alphabet = data;
+ size = alphabet.length();
+ scores = new float[size][];
+ continue;
+ }
+
+ /*
+ * too much information
+ */
+ if (row >= size)
+ {
+ err = "Unexpected extra input line in score model file: '" + data
+ + "'";
+ throw new FileFormatException(err);
+ }
+
+ /*
+ * subsequent lines should be the symbol scores
+ * optionally with the symbol as the first column for readability
+ */
+ StringTokenizer scoreLine = new StringTokenizer(data, DELIMITERS);
+ if (scoreLine.countTokens() == size + 1)
+ {
+ /*
+ * check 'guide' symbol is the row'th letter of the alphabet
+ */
+ String symbol = scoreLine.nextToken();
+ if (symbol.length() > 1 || symbol.charAt(0) != alphabet.charAt(row))
+ {
+ err = String
+ .format("Error parsing score matrix at line %d, expected '%s' but found '%s'",
+ lineNo, alphabet.charAt(row), symbol);
+ throw new FileFormatException(err);
+ }
+ }
+ if (scoreLine.countTokens() != size)
+ {
+ err = String.format("Expected %d scores at line %d but found %d",
+ size, lineNo, scoreLine.countTokens());
+ throw new FileFormatException(err);
+ }
+ scores[row] = new float[size];
+ int col = 0;
+ String value = null;
+ while (scoreLine.hasMoreTokens())
+ {
+ try
+ {
+ value = scoreLine.nextToken();
+ scores[row][col] = Float.valueOf(value);
+ col++;
+ } catch (NumberFormatException e)
+ {
+ err = String.format(
+ "Invalid score value '%s' at line %d column %d", value,
+ lineNo, col);
+ throw new FileFormatException(err);
+ }
+ }
+ row++;
+ }
+
+ /*
+ * out of data - check we found enough
+ */
+ if (row < size)
+ {
+ err = String
+ .format("Expected %d rows of score data in score matrix but only found %d",
+ size, row);
+ throw new FileFormatException(err);
+ }
+
+ /*
+ * If we get here, then name, alphabet and scores have been parsed successfully
+ */
+ sm = new ScoreMatrix(name, alphabet.toCharArray(), scores);
+ matrixName = name;
+
+ return sm;
+ }
+
+ public String getMatrixName()
+ {
+ return matrixName;
+ }
+}
prov.getEntry(0).addParam(new Param());
prov.getEntry(0).getParam(0).setName("treeType");
prov.getEntry(0).getParam(0).setType("utf8");
- prov.getEntry(0).getParam(0).setContent("NJ"); // TODO: type of tree is a
- // general parameter
+ prov.getEntry(0).getParam(0).setContent(NJTree.NEIGHBOUR_JOINING);
+ // TODO: type of tree is a general parameter
int ranges[] = tp.getTree().seqData.getVisibleContigs();
// VisibleContigs are with respect to alignment coordinates. Still need
// offsets
protected JMenu sort = new JMenu();
- protected JMenu calculateTree = new JMenu();
+ protected JMenuItem calculateTree = new JMenuItem();
protected JCheckBoxMenuItem padGapsMenuitem = new JCheckBoxMenuItem();
PCAMenuItem_actionPerformed(e);
}
});
- JMenuItem averageDistanceTreeMenuItem = new JMenuItem(
- MessageManager.getString("label.average_distance_identity"));
- averageDistanceTreeMenuItem.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- averageDistanceTreeMenuItem_actionPerformed(e);
- }
- });
- JMenuItem neighbourTreeMenuItem = new JMenuItem(
- MessageManager.getString("label.neighbour_joining_identity"));
- neighbourTreeMenuItem.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- neighbourTreeMenuItem_actionPerformed(e);
- }
- });
this.getContentPane().setLayout(new BorderLayout());
alignFrameMenuBar.setFont(new java.awt.Font("Verdana", 0, 11));
outputTextboxMenu.setText(MessageManager
.getString("label.out_to_textbox"));
-
- JMenuItem avDistanceTreeBlosumMenuItem = new JMenuItem(
- MessageManager.getString("label.average_distance_blosum62"));
- avDistanceTreeBlosumMenuItem.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- avTreeBlosumMenuItem_actionPerformed(e);
- }
- });
- JMenuItem njTreeBlosumMenuItem = new JMenuItem(
- MessageManager.getString("label.neighbour_blosum62"));
- njTreeBlosumMenuItem.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- njTreeBlosumMenuItem_actionPerformed(e);
- }
- });
annotationPanelMenuItem.setActionCommand("");
annotationPanelMenuItem.setText(MessageManager
.getString("label.show_annotations"));
@Override
public void menuSelected(MenuEvent e)
{
- buildTreeMenu();
+ buildTreeSortMenu();
}
@Override
{
}
- protected void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)
- {
- }
-
protected void neighbourTreeMenuItem_actionPerformed(ActionEvent e)
{
}
- protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)
- {
- }
-
- protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)
- {
- }
-
protected void conservationMenuItem_actionPerformed(boolean selected)
{
}
}
- public void buildTreeMenu()
+ public void buildTreeSortMenu()
{
}
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
+import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class GPCAPanel extends JInternalFrame
{
- JPanel jPanel2 = new JPanel();
+ private static final Font VERDANA_12 = new Font("Verdana", 0, 12);
- JLabel jLabel1 = new JLabel();
+ protected JComboBox<String> xCombobox = new JComboBox<String>();
- JLabel jLabel2 = new JLabel();
+ protected JComboBox<String> yCombobox = new JComboBox<String>();
- JLabel jLabel3 = new JLabel();
-
- protected JComboBox xCombobox = new JComboBox();
-
- protected JComboBox yCombobox = new JComboBox();
-
- protected JComboBox zCombobox = new JComboBox();
-
- protected JButton resetButton = new JButton();
-
- FlowLayout flowLayout1 = new FlowLayout();
-
- BorderLayout borderLayout1 = new BorderLayout();
-
- JMenuBar jMenuBar1 = new JMenuBar();
-
- JMenu fileMenu = new JMenu();
-
- JMenu saveMenu = new JMenu();
+ protected JComboBox<String> zCombobox = new JComboBox<String>();
protected JMenu scoreMatrixMenu = new JMenu();
- JMenuItem eps = new JMenuItem();
-
- JMenuItem png = new JMenuItem();
-
- JMenuItem print = new JMenuItem();
-
- JMenuItem outputValues = new JMenuItem();
-
- JMenuItem outputPoints = new JMenuItem();
-
- JMenuItem outputProjPoints = new JMenuItem();
-
protected JMenu viewMenu = new JMenu();
protected JCheckBoxMenuItem showLabels = new JCheckBoxMenuItem();
- JMenuItem bgcolour = new JMenuItem();
-
- JMenuItem originalSeqData = new JMenuItem();
-
protected JMenu associateViewsMenu = new JMenu();
protected JMenu calcSettings = new JMenu();
protected JLabel statusBar = new JLabel();
- protected GridLayout statusPanelLayout = new GridLayout();
-
protected JPanel statusPanel = new JPanel();
public GPCAPanel()
yCombobox.addItem("dim " + i);
zCombobox.addItem("dim " + i);
}
-
- setJMenuBar(jMenuBar1);
}
private void jbInit() throws Exception
{
- this.getContentPane().setLayout(borderLayout1);
- jPanel2.setLayout(flowLayout1);
- jLabel1.setFont(new java.awt.Font("Verdana", 0, 12));
+ this.getContentPane().setLayout(new BorderLayout());
+ JPanel jPanel2 = new JPanel();
+ jPanel2.setLayout(new FlowLayout());
+ JLabel jLabel1 = new JLabel();
+ jLabel1.setFont(VERDANA_12);
jLabel1.setText("x=");
- jLabel2.setFont(new java.awt.Font("Verdana", 0, 12));
+ JLabel jLabel2 = new JLabel();
+ jLabel2.setFont(VERDANA_12);
jLabel2.setText("y=");
- jLabel3.setFont(new java.awt.Font("Verdana", 0, 12));
+ JLabel jLabel3 = new JLabel();
+ jLabel3.setFont(VERDANA_12);
jLabel3.setText("z=");
jPanel2.setBackground(Color.white);
jPanel2.setBorder(null);
- zCombobox.setFont(new java.awt.Font("Verdana", 0, 12));
- zCombobox.addActionListener(new java.awt.event.ActionListener()
+ zCombobox.setFont(VERDANA_12);
+ zCombobox.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
zCombobox_actionPerformed(e);
}
});
- yCombobox.setFont(new java.awt.Font("Verdana", 0, 12));
- yCombobox.addActionListener(new java.awt.event.ActionListener()
+ yCombobox.setFont(VERDANA_12);
+ yCombobox.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
yCombobox_actionPerformed(e);
}
});
- xCombobox.setFont(new java.awt.Font("Verdana", 0, 12));
- xCombobox.addActionListener(new java.awt.event.ActionListener()
+ xCombobox.setFont(VERDANA_12);
+ xCombobox.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
xCombobox_actionPerformed(e);
}
});
- resetButton.setFont(new java.awt.Font("Verdana", 0, 12));
+ JButton resetButton = new JButton();
+ resetButton.setFont(VERDANA_12);
resetButton.setText(MessageManager.getString("action.reset"));
- resetButton.addActionListener(new java.awt.event.ActionListener()
+ resetButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
resetButton_actionPerformed(e);
}
});
+ JMenu fileMenu = new JMenu();
fileMenu.setText(MessageManager.getString("action.file"));
+ JMenu saveMenu = new JMenu();
saveMenu.setText(MessageManager.getString("action.save_as"));
- eps.setText("EPS");
+ JMenuItem eps = new JMenuItem("EPS");
eps.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
eps_actionPerformed(e);
}
});
- png.setText("PNG");
+ JMenuItem png = new JMenuItem("PNG");
png.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
png_actionPerformed(e);
}
});
+ JMenuItem outputValues = new JMenuItem();
outputValues.setText(MessageManager.getString("label.output_values"));
outputValues.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
outputValues_actionPerformed(e);
}
});
+ JMenuItem outputPoints = new JMenuItem();
outputPoints.setText(MessageManager.getString("label.output_points"));
outputPoints.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
outputPoints_actionPerformed(e);
}
});
+ JMenuItem outputProjPoints = new JMenuItem();
outputProjPoints.setText(MessageManager
.getString("label.output_transformed_points"));
outputProjPoints.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
outputProjPoints_actionPerformed(e);
}
});
+ JMenuItem print = new JMenuItem();
+ print.setText(MessageManager.getString("action.print"));
print.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
print_actionPerformed(e);
viewMenu.setText(MessageManager.getString("action.view"));
viewMenu.addMenuListener(new MenuListener()
{
+ @Override
public void menuSelected(MenuEvent e)
{
viewMenu_menuSelected();
}
+ @Override
public void menuDeselected(MenuEvent e)
{
}
+ @Override
public void menuCanceled(MenuEvent e)
{
}
.getString("label.select_score_model"));
scoreMatrixMenu.addMenuListener(new MenuListener()
{
+ @Override
public void menuSelected(MenuEvent e)
{
scoreMatrix_menuSelected();
}
+ @Override
public void menuDeselected(MenuEvent e)
{
}
+ @Override
public void menuCanceled(MenuEvent e)
{
}
showLabels.setText(MessageManager.getString("label.show_labels"));
showLabels.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
showLabels_actionPerformed(e);
}
});
- print.setText(MessageManager.getString("action.print"));
+ JMenuItem bgcolour = new JMenuItem();
bgcolour.setText(MessageManager.getString("action.background_colour"));
bgcolour.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
bgcolour_actionPerformed(e);
}
});
+ JMenuItem originalSeqData = new JMenuItem();
originalSeqData.setText(MessageManager.getString("label.input_data"));
originalSeqData.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
originalSeqData_actionPerformed(e);
jvVersionSetting_actionPerfomed(arg0);
}
});
- calcSettings.add(jvVersionSetting);
+ // calcSettings.add(jvVersionSetting); // todo remove? JAL-2416
calcSettings.add(nuclSetting);
calcSettings.add(protSetting);
calcSettings.add(scoreMatrixMenu);
- statusPanel.setLayout(statusPanelLayout);
- statusBar.setFont(new java.awt.Font("Verdana", 0, 12));
+ statusPanel.setLayout(new GridLayout());
+ statusBar.setFont(VERDANA_12);
// statusPanel.setBackground(Color.lightGray);
// statusBar.setBackground(Color.lightGray);
// statusPanel.add(statusBar, null);
jPanel2.add(jLabel3, null);
jPanel2.add(zCombobox, null);
jPanel2.add(resetButton, null);
+
+ JMenuBar jMenuBar1 = new JMenuBar();
jMenuBar1.add(fileMenu);
jMenuBar1.add(viewMenu);
jMenuBar1.add(calcSettings);
+ setJMenuBar(jMenuBar1);
fileMenu.add(saveMenu);
fileMenu.add(outputValues);
fileMenu.add(print);
*/
package jalview.schemes;
+import jalview.analysis.scoremodels.PairwiseScoreModelI;
+import jalview.analysis.scoremodels.ScoreModels;
import jalview.datamodel.AnnotatedCollectionI;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
public Color findColour(char res, int j, SequenceI seq,
String consensusResidue, float pid)
{
+ PairwiseScoreModelI sm = ScoreModels.getInstance().getBlosum62();
+
/*
* compare as upper case; note consensusResidue is
* always computed as uppercase
}
else
{
- int c = 0;
+ float score = 0;
for (char consensus : consensusResidue.toCharArray())
{
- c += ResidueProperties.getBLOSUM62(consensus, res);
+ score += sm.getPairwiseScore(consensus, res);
}
- if (c > 0)
+ if (score > 0)
{
colour = LIGHT_BLUE;
}
*/
package jalview.schemes;
-import jalview.analysis.scoremodels.FeatureScoreModel;
-import jalview.analysis.scoremodels.PIDScoreModel;
-import jalview.api.analysis.ScoreModelI;
-
import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
public class ResidueProperties
{
- public static Hashtable<String, ScoreModelI> scoreMatrices = new Hashtable<String, ScoreModelI>();
-
// Stores residue codes/names and colours and other things
public static final int[] aaIndex; // aaHash version 2.1.1 and below
// public static final double hydmax = 1.38;
// public static final double hydmin = -2.53;
- private static final int[][] BLOSUM62 = {
- { 4, -1, -2, -2, 0, -1, -1, 0, -2, -1, -1, -1, -1, -2, -1, 1, 0, -3,
- -2, 0, -2, -1, 0, -4 },
- { -1, 5, 0, -2, -3, 1, 0, -2, 0, -3, -2, 2, -1, -3, -2, -1, -1, -3,
- -2, -3, -1, 0, -1, -4 },
- { -2, 0, 6, 1, -3, 0, 0, 0, 1, -3, -3, 0, -2, -3, -2, 1, 0, -4, -2,
- -3, 3, 0, -1, -4 },
- { -2, -2, 1, 6, -3, 0, 2, -1, -1, -3, -4, -1, -3, -3, -1, 0, -1, -4,
- -3, -3, 4, 1, -1, -4 },
- { 0, -3, -3, -3, 9, -3, -4, -3, -3, -1, -1, -3, -1, -2, -3, -1, -1,
- -2, -2, -1, -3, -3, -2, -4 },
- { -1, 1, 0, 0, -3, 5, 2, -2, 0, -3, -2, 1, 0, -3, -1, 0, -1, -2, -1,
- -2, 0, 3, -1, -4 },
- { -1, 0, 0, 2, -4, 2, 5, -2, 0, -3, -3, 1, -2, -3, -1, 0, -1, -3, -2,
- -2, 1, 4, -1, -4 },
- { 0, -2, 0, -1, -3, -2, -2, 6, -2, -4, -4, -2, -3, -3, -2, 0, -2, -2,
- -3, -3, -1, -2, -1, -4 },
- { -2, 0, 1, -1, -3, 0, 0, -2, 8, -3, -3, -1, -2, -1, -2, -1, -2, -2,
- 2, -3, 0, 0, -1, -4 },
- { -1, -3, -3, -3, -1, -3, -3, -4, -3, 4, 2, -3, 1, 0, -3, -2, -1, -3,
- -1, 3, -3, -3, -1, -4 },
- { -1, -2, -3, -4, -1, -2, -3, -4, -3, 2, 4, -2, 2, 0, -3, -2, -1, -2,
- -1, 1, -4, -3, -1, -4 },
- { -1, 2, 0, -1, -3, 1, 1, -2, -1, -3, -2, 5, -1, -3, -1, 0, -1, -3,
- -2, -2, 0, 1, -1, -4 },
- { -1, -1, -2, -3, -1, 0, -2, -3, -2, 1, 2, -1, 5, 0, -2, -1, -1, -1,
- -1, 1, -3, -1, -1, -4 },
- { -2, -3, -3, -3, -2, -3, -3, -3, -1, 0, 0, -3, 0, 6, -4, -2, -2, 1,
- 3, -1, -3, -3, -1, -4 },
- { -1, -2, -2, -1, -3, -1, -1, -2, -2, -3, -3, -1, -2, -4, 7, -1, -1,
- -4, -3, -2, -2, -1, -2, -4 },
- { 1, -1, 1, 0, -1, 0, 0, 0, -1, -2, -2, 0, -1, -2, -1, 4, 1, -3, -2,
- -2, 0, 0, 0, -4 },
- { 0, -1, 0, -1, -1, -1, -1, -2, -2, -1, -1, -1, -1, -2, -1, 1, 5, -2,
- -2, 0, -1, -1, 0, -4 },
- { -3, -3, -4, -4, -2, -2, -3, -2, -2, -3, -2, -3, -1, 1, -4, -3, -2,
- 11, 2, -3, -4, -3, -2, -4 },
- { -2, -2, -2, -3, -2, -1, -2, -3, 2, -1, -1, -2, -1, 3, -3, -2, -2,
- 2, 7, -1, -3, -2, -1, -4 },
- { 0, -3, -3, -3, -1, -2, -2, -3, -3, 3, 1, -2, 1, -1, -2, -2, 0, -3,
- -1, 4, -3, -2, -1, -4 },
- { -2, -1, 3, 4, -3, 0, 1, -1, 0, -3, -4, 0, -3, -3, -2, 0, -1, -4,
- -3, -3, 4, 1, -1, -4 },
- { -1, 0, 0, 1, -3, 3, 4, -2, 0, -3, -3, 1, -1, -3, -1, 0, -1, -3, -2,
- -2, 1, 4, -1, -4 },
- { 0, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, 0, 0,
- -2, -1, -1, -1, -1, -1, -4 },
- { -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4,
- -4, -4, -4, -4, -4, -4, 1 }, };
-
- static final int[][] PAM250 = {
- { 2, -2, 0, 0, -2, 0, 0, 1, -1, -1, -2, -1, -1, -3, 1, 1, 1, -6, -3,
- 0, 0, 0, 0, -8 },
- { -2, 6, 0, -1, -4, 1, -1, -3, 2, -2, -3, 3, 0, -4, 0, 0, -1, 2, -4,
- -2, -1, 0, -1, -8 },
- { 0, 0, 2, 2, -4, 1, 1, 0, 2, -2, -3, 1, -2, -3, 0, 1, 0, -4, -2, -2,
- 2, 1, 0, -8 },
- { 0, -1, 2, 4, -5, 2, 3, 1, 1, -2, -4, 0, -3, -6, -1, 0, 0, -7, -4,
- -2, 3, 3, -1, -8 },
- { -2, -4, -4, -5, 12, -5, -5, -3, -3, -2, -6, -5, -5, -4, -3, 0, -2,
- -8, 0, -2, -4, -5, -3, -8 },
- { 0, 1, 1, 2, -5, 4, 2, -1, 3, -2, -2, 1, -1, -5, 0, -1, -1, -5, -4,
- -2, 1, 3, -1, -8 },
- { 0, -1, 1, 3, -5, 2, 4, 0, 1, -2, -3, 0, -2, -5, -1, 0, 0, -7, -4,
- -2, 3, 3, -1, -8 },
- { 1, -3, 0, 1, -3, -1, 0, 5, -2, -3, -4, -2, -3, -5, 0, 1, 0, -7, -5,
- -1, 0, 0, -1, -8 },
- { -1, 2, 2, 1, -3, 3, 1, -2, 6, -2, -2, 0, -2, -2, 0, -1, -1, -3, 0,
- -2, 1, 2, -1, -8 },
- { -1, -2, -2, -2, -2, -2, -2, -3, -2, 5, 2, -2, 2, 1, -2, -1, 0, -5,
- -1, 4, -2, -2, -1, -8 },
- { -2, -3, -3, -4, -6, -2, -3, -4, -2, 2, 6, -3, 4, 2, -3, -3, -2, -2,
- -1, 2, -3, -3, -1, -8 },
- { -1, 3, 1, 0, -5, 1, 0, -2, 0, -2, -3, 5, 0, -5, -1, 0, 0, -3, -4,
- -2, 1, 0, -1, -8 },
- { -1, 0, -2, -3, -5, -1, -2, -3, -2, 2, 4, 0, 6, 0, -2, -2, -1, -4,
- -2, 2, -2, -2, -1, -8 },
- { -3, -4, -3, -6, -4, -5, -5, -5, -2, 1, 2, -5, 0, 9, -5, -3, -3, 0,
- 7, -1, -4, -5, -2, -8 },
- { 1, 0, 0, -1, -3, 0, -1, 0, 0, -2, -3, -1, -2, -5, 6, 1, 0, -6, -5,
- -1, -1, 0, -1, -8 },
- { 1, 0, 1, 0, 0, -1, 0, 1, -1, -1, -3, 0, -2, -3, 1, 2, 1, -2, -3,
- -1, 0, 0, 0, -8 },
- { 1, -1, 0, 0, -2, -1, 0, 0, -1, 0, -2, 0, -1, -3, 0, 1, 3, -5, -3,
- 0, 0, -1, 0, -8 },
- { -6, 2, -4, -7, -8, -5, -7, -7, -3, -5, -2, -3, -4, 0, -6, -2, -5,
- 17, 0, -6, -5, -6, -4, -8 },
- { -3, -4, -2, -4, 0, -4, -4, -5, 0, -1, -1, -4, -2, 7, -5, -3, -3, 0,
- 10, -2, -3, -4, -2, -8 },
- { 0, -2, -2, -2, -2, -2, -2, -1, -2, 4, 2, -2, 2, -1, -1, -1, 0, -6,
- -2, 4, -2, -2, -1, -8 },
- { 0, -1, 2, 3, -4, 1, 3, 0, 1, -2, -3, 1, -2, -4, -1, 0, 0, -5, -3,
- -2, 3, 2, -1, -8 },
- { 0, 0, 1, 3, -5, 3, 3, 0, 2, -2, -3, 0, -2, -5, 0, 0, -1, -6, -4,
- -2, 2, 3, -1, -8 },
- { 0, -1, 0, -1, -3, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, 0, 0, -4,
- -2, -1, -1, -1, -1, -8 },
- { -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
- -8, -8, -8, -8, -8, -8, 1 }, };
// not currently used
// public static final Map<String, Color> ssHash = new Hashtable<String,
* Color.white, // R Color.white, // Y Color.white, // N Color.white, // Gap
*/
- // JBPNote: patch matrix for T/U equivalence when working with DNA or RNA.
- // Will equate sequences if working with mixed nucleotide sets.
- // treats T and U identically. R and Y weak equivalence with AG and CTU.
- // N matches any other base weakly
- //
- static final int[][] DNA = { { 10, -8, -8, -8, -8, 1, 1, 1, -8, 1, 1 }, // A
- { -8, 10, -8, -8, -8, 1, 1, -8, 1, 1, 1 }, // C
- { -8, -8, 10, -8, -8, 1, 1, 1, -8, 1, 1 }, // G
- { -8, -8, -8, 10, 10, 1, 1, -8, 1, 1, 1 }, // T
- { -8, -8, -8, 10, 10, 1, 1, -8, 1, 1, 1 }, // U
- { 1, 1, 1, 1, 1, 10, 0, 0, 0, 1, 1 }, // I
- { 1, 1, 1, 1, 1, 0, 10, 0, 0, 1, 1 }, // X
- { 1, -8, 1, -8, -8, 0, 0, 10, -8, 1, 1 }, // R
- { -8, 1, -8, 1, 1, 0, 0, -8, 10, 1, 1 }, // Y
- { 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 1 }, // N
- { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // -
- };
- /**
- * register matrices in list
- */
- static
- {
- scoreMatrices.put("BLOSUM62", new ScoreMatrix("BLOSUM62", BLOSUM62, 0));
- scoreMatrices.put("PAM250", new ScoreMatrix("PAM250", PAM250, 0));
- scoreMatrices.put("DNA", new ScoreMatrix("DNA", DNA, 1));
- }
-
public static List<String> STOP = Arrays.asList("TGA", "TAA", "TAG");
public static String START = "ATG";
propMatrixPos[i][i] = maxP;
propMatrixEpos[i][i] = maxEP;
}
- // JAL-1512 comment out physicochemical score matrices for 2.8.1 release
- // scoreMatrices.put("Conservation Pos", new
- // ScoreMatrix("Conservation Pos",propMatrixPos,0));
- // scoreMatrices.put("Conservation Both", new
- // ScoreMatrix("Conservation Both",propMatrixF,0));
- // scoreMatrices.put("Conservation EnhPos", new
- // ScoreMatrix("Conservation EnhPos",propMatrixEpos,0));
- scoreMatrices.put("PID", new PIDScoreModel());
- scoreMatrices.put("Displayed Features", new FeatureScoreModel());
}
private ResidueProperties()
return aa3Hash;
}
- public static int[][] getDNA()
- {
- return ResidueProperties.DNA;
- }
-
- public static int[][] getBLOSUM62()
- {
- return ResidueProperties.BLOSUM62;
- }
-
- public static int getPAM250(String A1, String A2)
- {
- return getPAM250(A1.charAt(0), A2.charAt(0));
- }
-
- public static int getBLOSUM62(char c1, char c2)
- {
- int pog = 0;
-
- try
- {
- int a = aaIndex[c1];
- int b = aaIndex[c2];
-
- pog = ResidueProperties.BLOSUM62[a][b];
- } catch (Exception e)
- {
- // System.out.println("Unknown residue in " + A1 + " " + A2);
- }
-
- return pog;
- }
-
public static String codonTranslate(String lccodon)
{
String cdn = codonHash2.get(lccodon.toUpperCase());
return cdn;
}
- public static int[][] getDefaultPeptideMatrix()
- {
- return ResidueProperties.getBLOSUM62();
- }
-
- public static int[][] getDefaultDnaMatrix()
- {
- return ResidueProperties.getDNA();
- }
-
- /**
- * get a ScoreMatrix based on its string name
- *
- * @param pwtype
- * @return matrix in scoreMatrices with key pwtype or null
- */
- public static ScoreMatrix getScoreMatrix(String pwtype)
- {
- Object val = scoreMatrices.get(pwtype);
- if (val != null && val instanceof ScoreMatrix)
- {
- return (ScoreMatrix) val;
- }
- return null;
- }
-
- /**
- * get a ScoreModel based on its string name
- *
- * @param pwtype
- * @return scoremodel of type pwtype or null
- */
- public static ScoreModelI getScoreModel(String pwtype)
- {
- return scoreMatrices.get(pwtype);
- }
-
- public static int getPAM250(char c, char d)
- {
- int a = aaIndex[c];
- int b = aaIndex[d];
-
- int pog = ResidueProperties.PAM250[a][b];
-
- return pog;
- }
-
public static Hashtable<String, String> toDssp3State;
static
{
+++ /dev/null
-/*
- * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
- * Copyright (C) $$Year-Rel$$ The Jalview Authors
- *
- * This file is part of Jalview.
- *
- * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *
- * Jalview 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
-package jalview.schemes;
-
-import jalview.analysis.scoremodels.PairwiseSeqScoreModel;
-import jalview.math.Matrix;
-import jalview.math.MatrixI;
-
-public class ScoreMatrix extends PairwiseSeqScoreModel
-{
- String name;
-
- @Override
- public String getName()
- {
- return name;
- }
-
- /**
- * reference to integer score matrix
- */
- int[][] matrix;
-
- /**
- * 0 for Protein Score matrix. 1 for dna score matrix
- */
- int type;
-
- /**
- *
- * @param name
- * Unique, human readable name for the matrix
- * @param matrix
- * Pairwise scores indexed according to appropriate symbol alphabet
- * @param type
- * 0 for Protein, 1 for NA
- */
- ScoreMatrix(String name, int[][] matrix, int type)
- {
- this.matrix = matrix;
- this.type = type;
- this.name = name;
- }
-
- @Override
- public boolean isDNA()
- {
- return type == 1;
- }
-
- @Override
- public boolean isProtein()
- {
- return type == 0;
- }
-
- @Override
- public int[][] getMatrix()
- {
- return matrix;
- }
-
- /**
- * Answers the score for substituting first char in A1 with first char in A2
- *
- * @param A1
- * @param A2
- * @return
- */
- public int getPairwiseScore(String A1, String A2)
- {
- return getPairwiseScore(A1.charAt(0), A2.charAt(0));
- }
-
- @Override
- public int getPairwiseScore(char c, char d)
- {
- int score = 0;
-
- try
- {
- int a = (type == 0) ? ResidueProperties.aaIndex[c]
- : ResidueProperties.nucleotideIndex[c];
- int b = (type == 0) ? ResidueProperties.aaIndex[d]
- : ResidueProperties.nucleotideIndex[d];
- score = matrix[a][b];
- } catch (Exception e)
- {
- // System.out.println("Unknown residue in " + A1 + " " + A2);
- }
-
- return score;
- }
-
- /**
- * pretty print the matrix
- */
- @Override
- public String toString()
- {
- return outputMatrix(false);
- }
-
- public String outputMatrix(boolean html)
- {
- StringBuffer sb = new StringBuffer();
- int[] symbols = (type == 0) ? ResidueProperties.aaIndex
- : ResidueProperties.nucleotideIndex;
- int symMax = (type == 0) ? ResidueProperties.maxProteinIndex
- : ResidueProperties.maxNucleotideIndex;
- boolean header = true;
- if (html)
- {
- sb.append("<table border=\"1\">");
- }
- for (char sym = 'A'; sym <= 'Z'; sym++)
- {
- if (symbols[sym] >= 0 && symbols[sym] < symMax)
- {
- if (header)
- {
- sb.append(html ? "<tr><td></td>" : "");
- for (char sym2 = 'A'; sym2 <= 'Z'; sym2++)
- {
- if (symbols[sym2] >= 0 && symbols[sym2] < symMax)
- {
- sb.append((html ? "<td> " : "\t") + sym2
- + (html ? " </td>" : ""));
- }
- }
- header = false;
- sb.append(html ? "</tr>\n" : "\n");
- }
- if (html)
- {
- sb.append("<tr>");
- }
- sb.append((html ? "<td>" : "") + sym + (html ? "</td>" : ""));
- for (char sym2 = 'A'; sym2 <= 'Z'; sym2++)
- {
- if (symbols[sym2] >= 0 && symbols[sym2] < symMax)
- {
- sb.append((html ? "<td>" : "\t")
- + matrix[symbols[sym]][symbols[sym2]]
- + (html ? "</td>" : ""));
- }
- }
- sb.append(html ? "</tr>\n" : "\n");
- }
- }
- if (html)
- {
- sb.append("</table>");
- }
- return sb.toString();
- }
-
- /**
- * Computes an NxN matrix where N is the number of sequences, and entry [i, j]
- * is sequence[i] pairwise multiplied with sequence[j], as a sum of scores
- * computed using the current score matrix. For example
- * <ul>
- * <li>Sequences:</li>
- * <li>FKL</li>
- * <li>R-D</li>
- * <li>QIA</li>
- * <li>GWC</li>
- * <li>Score matrix is BLOSUM62</li>
- * <li>Gaps treated same as X (unknown)</li>
- * <li>product [0, 0] = F.F + K.K + L.L = 6 + 5 + 4 = 15</li>
- * <li>product [1, 1] = R.R + -.- + D.D = 5 + -1 + 6 = 10</li>
- * <li>product [2, 2] = Q.Q + I.I + A.A = 5 + 4 + 4 = 13</li>
- * <li>product [3, 3] = G.G + W.W + C.C = 6 + 11 + 9 = 26</li>
- * <li>product[0, 1] = F.R + K.- + L.D = -3 + -1 + -3 = -8
- * <li>and so on</li>
- * </ul>
- */
- public MatrixI computePairwiseScores(String[] seqs)
- {
- double[][] values = new double[seqs.length][];
- for (int row = 0; row < seqs.length; row++)
- {
- values[row] = new double[seqs.length];
- for (int col = 0; col < seqs.length; col++)
- {
- int total = 0;
- int width = Math.min(seqs[row].length(), seqs[col].length());
- for (int i = 0; i < width; i++)
- {
- char c1 = seqs[row].charAt(i);
- char c2 = seqs[col].charAt(i);
- int score = getPairwiseScore(c1, c2);
- total += score;
- }
- values[row][col] = total;
- }
- }
- return new Matrix(values);
- }
-}
* Attempt pairwise alignment of the sequence with each chain in the PDB,
* and remember the highest scoring chain
*/
- int max = -10;
+ float max = -10;
AlignSeq maxAlignseq = null;
String maxChainId = " ";
PDBChain maxChain = null;
private static final int TO_UPPER_CASE = 'a' - 'A';
- private static final char GAP_SPACE = ' ';
+ public static final char GAP_SPACE = ' ';
- private static final char GAP_DOT = '.';
+ public static final char GAP_DOT = '.';
- private static final char GAP_DASH = '-';
+ public static final char GAP_DASH = '-';
public static final String GapChars = new String(new char[] { GAP_SPACE,
GAP_DOT, GAP_DASH });
--- /dev/null
+package jalview.util;
+
+import java.util.Set;
+
+public class SetUtils
+{
+ /**
+ * Returns the count of things that are one or other of two sets but not in
+ * both. The sets are not modified.
+ *
+ * @param set1
+ * @param set2
+ * @return
+ */
+ public static int countDisjunction(Set<? extends Object> set1,
+ Set<? extends Object> set2)
+ {
+ if (set1 == null)
+ {
+ return set2 == null ? 0 : set2.size();
+ }
+ if (set2 == null)
+ {
+ return set1.size();
+ }
+
+ int size1 = set1.size();
+ int size2 = set2.size();
+ Set<? extends Object> smallerSet = size1 < size2 ? set1 : set2;
+ Set<? extends Object> largerSet = (smallerSet == set1 ? set2 : set1);
+ int inCommon = 0;
+ for (Object k : smallerSet)
+ {
+ if (largerSet.contains(k))
+ {
+ inCommon++;
+ }
+ }
+
+ int notInCommon = (size1 - inCommon) + (size2 - inCommon);
+ return notInCommon;
+ }
+}
seqstrings = seqstrings2;
seqs = seqs2;
nucleotide = nucleotide2;
- score_matrix = nucleotide2 ? "PID" : "BLOSUM62";
+ score_matrix = nucleotide2 ? "DNA" : "BLOSUM62";
}
private volatile PCA pca;
package jalview.ws.sifts;
import jalview.analysis.AlignSeq;
+import jalview.analysis.scoremodels.ScoreMatrix;
+import jalview.analysis.scoremodels.ScoreModels;
import jalview.api.DBRefEntryI;
import jalview.api.SiftsClientI;
import jalview.datamodel.DBRefEntry;
}
@Override
- public StringBuffer getMappingOutput(MappingOutputPojo mp)
+ public StringBuilder getMappingOutput(MappingOutputPojo mp)
throws SiftsException
{
String seqRes = mp.getSeqResidue();
int nochunks = ((seqRes.length()) / len)
+ ((seqRes.length()) % len > 0 ? 1 : 0);
// output mappings
- StringBuffer output = new StringBuffer();
+ StringBuilder output = new StringBuilder(512);
output.append(NEWLINE);
output.append("Sequence \u27f7 Structure mapping details").append(
NEWLINE);
output.append(String.valueOf(pdbEnd));
output.append(NEWLINE).append(NEWLINE);
+ ScoreMatrix pam250 = ScoreModels.getInstance().getPam250();
int matchedSeqCount = 0;
for (int j = 0; j < nochunks; j++)
{
output.append(NEWLINE);
output.append(new Format("%" + (maxid) + "s").form(" ")).append(" ");
- // Print out the matching chars
+ /*
+ * Print out the match symbols:
+ * | for exact match (ignoring case)
+ * . if PAM250 score is positive
+ * else a space
+ */
for (int i = 0; i < len; i++)
{
try
{
if ((i + (j * len)) < seqRes.length())
{
- boolean sameChar = Comparison.isSameResidue(
- seqRes.charAt(i + (j * len)),
- strRes.charAt(i + (j * len)), false);
- if (sameChar
- && !jalview.util.Comparison.isGap(seqRes.charAt(i
- + (j * len))))
+ char c1 = seqRes.charAt(i + (j * len));
+ char c2 = strRes.charAt(i + (j * len));
+ boolean sameChar = Comparison.isSameResidue(c1, c2, false);
+ if (sameChar && !Comparison.isGap(c1))
{
matchedSeqCount++;
output.append("|");
}
else if (type.equals("pep"))
{
- if (ResidueProperties.getPAM250(seqRes.charAt(i + (j * len)),
- strRes.charAt(i + (j * len))) > 0)
+ if (pam250.getPairwiseScore(c1, c2) > 0)
{
output.append(".");
}
*/
package jalview.analysis;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
+import jalview.datamodel.Sequence;
import jalview.gui.JvOptionPane;
import org.testng.annotations.BeforeClass;
assertNull(AlignSeq.extractGaps(null, "ACG"));
assertNull(AlignSeq.extractGaps("-. ", null));
- assertEquals(" AC-G.T", AlignSeq.extractGaps("", " AC-G.T"));
- assertEquals("AC-G.T", AlignSeq.extractGaps(" ", " AC-G.T"));
- assertEquals("ACG.T", AlignSeq.extractGaps(" -", " AC-G.T"));
- assertEquals("ACGT", AlignSeq.extractGaps(" -.", " AC-G.T ."));
- assertEquals(" ACG.T", AlignSeq.extractGaps("-", " AC-G.T"));
+ assertEquals(AlignSeq.extractGaps("", " AC-G.T"), " AC-G.T");
+ assertEquals(AlignSeq.extractGaps(" ", " AC-G.T"), "AC-G.T");
+ assertEquals(AlignSeq.extractGaps(" -", " AC-G.T"), "ACG.T");
+ assertEquals(AlignSeq.extractGaps(" -.", " AC-G.T ."), "ACGT");
+ assertEquals(AlignSeq.extractGaps("-", " AC-G.T"), " ACG.T");
+ }
+
+ @Test(groups = { "Functional" })
+ public void testIndexEncode_nucleotide()
+ {
+ AlignSeq as = new AlignSeq(new Sequence("s1", "TTAG"), new Sequence(
+ "s2", "ACGT"), AlignSeq.DNA);
+ int[] expected = new int[] { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, -1, 11, -1 };
+ String s = "aAcCgGtTuUiIxXrRyYnN .-?";
+ assertArrayEquals(expected, as.indexEncode(s));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testIndexEncode_peptide()
+ {
+ AlignSeq as = new AlignSeq(new Sequence("s1", "PFY"), new Sequence(
+ "s2", "RQW"), AlignSeq.PEP);
+ int[] expected = new int[] { 0, 0, 1, 1, 2, 2, 21, 21, 22, 22, 23, 24,
+ -1, -1, -1 };
+ String s = "aArRnNzZxX *.-?";
+ assertArrayEquals(expected, as.indexEncode(s));
}
}
};
as.printAlignment(ps);
- String expected = "Score = 320\nLength of alignment = 10\nSequence Seq1 : 3 - 18 (Sequence length = 14)\nSequence Seq1 : 1 - 10 (Sequence length = 10)\n\n"
+ String expected = "Score = 320.0\nLength of alignment = 10\nSequence Seq1 : 3 - 18 (Sequence length = 14)\nSequence Seq1 : 1 - 10 (Sequence length = 10)\n\n"
+ "Seq1 SDFAQQQRRR\n"
+ " ||||||| \n"
+ "Seq1 SDFAQQQSSS\n\n" + "Percentage ID = 70.00\n";
*/
package jalview.analysis.scoremodels;
+import static org.testng.Assert.assertEquals;
+
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
-public class FeatureScoreModelTest
+public class FeatureDistanceModelTest
{
@BeforeClass(alwaysRun = true)
int[] sf3 = new int[] { -1, -1, -1, -1, -1, -1, 76, 77 };
+ /**
+ * <pre>
+ * Load test alignment and add features to sequences:
+ * FER1_MESCR FER1_SPIOL FER3_RAPSA FER1_MAIZE
+ * sf1 X X X
+ * sf2 X X
+ * sf3 X
+ * </pre>
+ *
+ * @return
+ */
public AlignFrame getTestAlignmentFrame()
{
AlignFrame alf = new FileLoader(false).LoadFileWaitTillLoaded(
public void testFeatureScoreModel() throws Exception
{
AlignFrame alf = getTestAlignmentFrame();
- FeatureScoreModel fsm = new FeatureScoreModel();
+ FeatureDistanceModel fsm = new FeatureDistanceModel();
Assert.assertTrue(fsm.configureFromAlignmentView(alf.getCurrentView()
.getAlignPanel()));
alf.selectAllSequenceMenuItem_actionPerformed(null);
+
float[][] dm = fsm.findDistances(alf.getViewport().getAlignmentView(
true));
Assert.assertTrue(dm[0][2] == 0f,
AlignFrame alf = getTestAlignmentFrame();
// hiding first two columns shouldn't affect the tree
alf.getViewport().hideColumns(0, 1);
- FeatureScoreModel fsm = new FeatureScoreModel();
+ FeatureDistanceModel fsm = new FeatureDistanceModel();
Assert.assertTrue(fsm.configureFromAlignmentView(alf.getCurrentView()
.getAlignPanel()));
alf.selectAllSequenceMenuItem_actionPerformed(null);
// hide columns and check tree changes
alf.getViewport().hideColumns(3, 4);
alf.getViewport().hideColumns(0, 1);
- FeatureScoreModel fsm = new FeatureScoreModel();
+ FeatureDistanceModel fsm = new FeatureDistanceModel();
Assert.assertTrue(fsm.configureFromAlignmentView(alf.getCurrentView()
.getAlignPanel()));
alf.selectAllSequenceMenuItem_actionPerformed(null);
.size(), 0);
}
+ @Test(groups = { "Functional" })
+ public void testFindDistances() throws Exception
+ {
+ String seqs = ">s1\nABCDE\n>seq2\nABCDE\n";
+ AlignFrame alf = new FileLoader().LoadFileWaitTillLoaded(seqs,
+ DataSourceType.PASTE);
+ SequenceI s1 = alf.getViewport().getAlignment().getSequenceAt(0);
+ SequenceI s2 = alf.getViewport().getAlignment().getSequenceAt(1);
+
+ /*
+ * set domain and variant features thus:
+ * ----5
+ * s1 ddd..
+ * s1 .vvv.
+ * s1 ..vvv
+ * s2 .ddd.
+ * s2 vv..v
+ * The number of unshared feature types per column is
+ * 20120 (two features of the same type doesn't affect score)
+ * giving an average (pairwise distance) of 5/5 or 1.0
+ */
+ s1.addSequenceFeature(new SequenceFeature("domain", null, 1, 3, 0f,
+ null));
+ s1.addSequenceFeature(new SequenceFeature("variant", null, 2, 4, 0f,
+ null));
+ s1.addSequenceFeature(new SequenceFeature("variant", null, 3, 5, 0f,
+ null));
+ s2.addSequenceFeature(new SequenceFeature("domain", null, 2, 4, 0f,
+ null));
+ s2.addSequenceFeature(new SequenceFeature("variant", null, 1, 2, 0f,
+ null));
+ s2.addSequenceFeature(new SequenceFeature("variant", null, 5, 5, 0f,
+ null));
+ alf.setShowSeqFeatures(true);
+ alf.getFeatureRenderer().findAllFeatures(true);
+
+ FeatureDistanceModel fsm = new FeatureDistanceModel();
+ Assert.assertTrue(fsm.configureFromAlignmentView(alf.getCurrentView()
+ .getAlignPanel()));
+ alf.selectAllSequenceMenuItem_actionPerformed(null);
+
+ float[][] distances = fsm.findDistances(alf.getViewport()
+ .getAlignmentView(true));
+ assertEquals(distances.length, 2);
+ assertEquals(distances[0][0], 0f);
+ assertEquals(distances[1][1], 0f);
+ // these left to fail pending resolution of
+ // JAL-2424 (dividing score by 6, not 5)
+ assertEquals(distances[0][1], 1f);
+ assertEquals(distances[1][0], 1f);
+ }
+
}
--- /dev/null
+package jalview.analysis.scoremodels;
+import static org.testng.Assert.assertEquals;
+import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
+
+import jalview.math.MatrixI;
+
+import org.testng.annotations.Test;
+
+public class ScoreMatrixTest
+{
+ @Test(groups = "Functional")
+ public void testConstructor()
+ {
+ // note score matrix does not have to be symmetric (though it should be!)
+ float[][] scores = new float[3][];
+ scores[0] = new float[] { 1f, 2f, 3f };
+ scores[1] = new float[] { 4f, 5f, 6f };
+ scores[2] = new float[] { 7f, 8f, 9f };
+ ScoreMatrix sm = new ScoreMatrix("Test", "ABC".toCharArray(), scores);
+ assertEquals(sm.getSize(), 3);
+ assertArrayEquals(scores, sm.getMatrix());
+ assertEquals(sm.getPairwiseScore('A', 'a'), 1f);
+ assertEquals(sm.getPairwiseScore('b', 'c'), 6f);
+ assertEquals(sm.getPairwiseScore('c', 'b'), 8f);
+ assertEquals(sm.getPairwiseScore('A', 'D'), 0f);
+ assertEquals(sm.getMatrixIndex('c'), 2);
+ assertEquals(sm.getMatrixIndex(' '), -1);
+ }
+
+ @Test(
+ groups = "Functional",
+ expectedExceptions = { IllegalArgumentException.class })
+ public void testConstructor_matrixTooSmall()
+ {
+ float[][] scores = new float[2][];
+ scores[0] = new float[] { 1f, 2f };
+ scores[1] = new float[] { 3f, 4f };
+ new ScoreMatrix("Test", "ABC".toCharArray(), scores);
+ }
+
+ @Test(
+ groups = "Functional",
+ expectedExceptions = { IllegalArgumentException.class })
+ public void testConstructor_matrixTooBig()
+ {
+ float[][] scores = new float[2][];
+ scores[0] = new float[] { 1f, 2f };
+ scores[1] = new float[] { 3f, 4f };
+ new ScoreMatrix("Test", "A".toCharArray(), scores);
+ }
+
+ @Test(
+ groups = "Functional",
+ expectedExceptions = { IllegalArgumentException.class })
+ public void testConstructor_matrixNotSquare()
+ {
+ float[][] scores = new float[2][];
+ scores[0] = new float[] { 1f, 2f };
+ scores[1] = new float[] { 3f };
+ new ScoreMatrix("Test", "AB".toCharArray(), scores);
+ }
+
+ @Test(groups = "Functional")
+ public void testBuildSymbolIndex()
+ {
+ short[] index = ScoreMatrix.buildSymbolIndex("AX-. yxYp".toCharArray());
+
+ assertEquals(index.length, 128); // ASCII character set size
+
+ assertEquals(index['A'], 0);
+ assertEquals(index['a'], 0); // lower-case mapping added
+ assertEquals(index['X'], 1);
+ assertEquals(index['-'], 2);
+ assertEquals(index['.'], 3);
+ assertEquals(index[' '], 4);
+ assertEquals(index['y'], 5); // lower-case override
+ assertEquals(index['x'], 6); // lower-case override
+ assertEquals(index['Y'], 7);
+ assertEquals(index['p'], 8);
+ assertEquals(index['P'], -1); // lower-case doesn't map upper-case
+
+ /*
+ * check all unmapped symbols have index for unmapped
+ */
+ for (int c = 0; c < index.length; c++)
+ {
+ if (!"AaXx-. Yyp".contains(String.valueOf((char) c)))
+ {
+ assertEquals(index[c], -1);
+ }
+ }
+ }
+
+ /**
+ * check that characters not in the basic ASCII set are simply ignored
+ */
+ @Test(groups = "Functional")
+ public void testBuildSymbolIndex_nonAscii()
+ {
+ char[] weird = new char[] { 128, 245, 'P' };
+ short[] index = ScoreMatrix.buildSymbolIndex(weird);
+ assertEquals(index.length, 128);
+ assertEquals(index['P'], 2);
+ assertEquals(index['p'], 2);
+ for (int c = 0; c < index.length; c++)
+ {
+ if (c != 'P' && c != 'p')
+ {
+ assertEquals(index[c], -1);
+ }
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testGetMatrixIndex()
+ {
+ ScoreMatrix sm = ScoreModels.getInstance().getBlosum62();
+ assertEquals(sm.getMatrixIndex('A'), 0);
+ assertEquals(sm.getMatrixIndex('R'), 1);
+ assertEquals(sm.getMatrixIndex('r'), 1);
+ assertEquals(sm.getMatrixIndex('N'), 2);
+ assertEquals(sm.getMatrixIndex('D'), 3);
+ assertEquals(sm.getMatrixIndex('X'), 22);
+ assertEquals(sm.getMatrixIndex('x'), 22);
+ assertEquals(sm.getMatrixIndex(' '), 23);
+ assertEquals(sm.getMatrixIndex('*'), 24);
+ assertEquals(sm.getMatrixIndex('.'), -1);
+ assertEquals(sm.getMatrixIndex('-'), -1);
+ assertEquals(sm.getMatrixIndex('?'), -1);
+ assertEquals(sm.getMatrixIndex((char) 128), -1);
+ }
+
+ @Test(groups = "Functional")
+ public void testGetSize()
+ {
+ ScoreMatrix sm = ScoreModels.getInstance().getBlosum62();
+ assertEquals(sm.getMatrix().length, sm.getSize());
+ }
+
+ @Test(groups = "Functional")
+ public void testComputePairwiseScores()
+ {
+ /*
+ * NB score matrix assumes space for gap - Jalview converts
+ * space to gap before computing PCA or Tree
+ */
+ String[] seqs = new String[] { "FKL", "R D", "QIA", "GWC" };
+ ScoreMatrix sm = ScoreModels.getInstance().getBlosum62();
+
+ MatrixI pairwise = sm.computePairwiseScores(seqs);
+
+ /*
+ * should be NxN where N = number of sequences
+ */
+ assertEquals(pairwise.height(), 4);
+ assertEquals(pairwise.width(), 4);
+
+ /*
+ * should be symmetrical (because BLOSUM62 is)
+ */
+ for (int i = 0; i < pairwise.height(); i++)
+ {
+ for (int j = i + 1; j < pairwise.width(); j++)
+ {
+ assertEquals(pairwise.getValue(i, j), pairwise.getValue(j, i),
+ String.format("Not symmetric at [%d, %d]", i, j));
+ }
+ }
+ /*
+ * verify expected BLOSUM dot product scores
+ */
+ // F.F + K.K + L.L = 6 + 5 + 4 = 15
+ assertEquals(pairwise.getValue(0, 0), 15d);
+ // R.R + -.- + D.D = 5 + 1 + 6 = 12
+ assertEquals(pairwise.getValue(1, 1), 12d);
+ // Q.Q + I.I + A.A = 5 + 4 + 4 = 13
+ assertEquals(pairwise.getValue(2, 2), 13d);
+ // G.G + W.W + C.C = 6 + 11 + 9 = 26
+ assertEquals(pairwise.getValue(3, 3), 26d);
+ // F.R + K.- + L.D = -3 + -4 + -4 = -11
+ assertEquals(pairwise.getValue(0, 1), -11d);
+ // F.Q + K.I + L.A = -3 + -3 + -1 = -7
+ assertEquals(pairwise.getValue(0, 2), -7d);
+ // F.G + K.W + L.C = -3 + -3 + -1 = -7
+ assertEquals(pairwise.getValue(0, 3), -7d);
+ // R.Q + -.I + D.A = 1 + -4 + -2 = -5
+ assertEquals(pairwise.getValue(1, 2), -5d);
+ // R.G + -.W + D.C = -2 + -4 + -3 = -9
+ assertEquals(pairwise.getValue(1, 3), -9d);
+ // Q.G + I.W + A.C = -2 + -3 + 0 = -5
+ assertEquals(pairwise.getValue(2, 3), -5d);
+ }
+}
--- /dev/null
+package jalview.analysis.scoremodels;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import jalview.api.analysis.DistanceModelI;
+
+import java.util.Iterator;
+
+import org.testng.annotations.Test;
+
+public class ScoreModelsTest
+{
+ /**
+ * Verify that the singleton constructor successfully loads Jalview's built-in
+ * score models
+ */
+ @Test
+ public void testConstructor()
+ {
+ Iterator<DistanceModelI> models = ScoreModels.getInstance().getModels()
+ .iterator();
+ assertTrue(models.hasNext());
+
+ /*
+ * models are served in order of addition
+ */
+ DistanceModelI sm = models.next();
+ assertTrue(sm instanceof PairwiseDistanceModel);
+ assertEquals(sm.getName(), "BLOSUM62");
+ assertEquals(((PairwiseDistanceModel) sm).getScoreModel()
+ .getPairwiseScore('I', 'R'), -3f);
+
+ sm = models.next();
+ assertTrue(sm instanceof PairwiseDistanceModel);
+ assertEquals(sm.getName(), "PAM250");
+ assertEquals(((PairwiseDistanceModel) sm).getScoreModel()
+ .getPairwiseScore('R', 'C'), -4f);
+
+ sm = models.next();
+ assertTrue(sm instanceof PairwiseDistanceModel);
+ assertEquals(sm.getName(), "Identity (SeqSpace)");
+ assertEquals(((PairwiseDistanceModel) sm).getScoreModel()
+ .getPairwiseScore('R', 'C'), 0f);
+ assertEquals(((PairwiseDistanceModel) sm).getScoreModel()
+ .getPairwiseScore('R', 'r'), 1f);
+
+ sm = models.next();
+ assertTrue(sm instanceof PairwiseDistanceModel);
+ assertEquals(sm.getName(), "DNA");
+ assertEquals(((PairwiseDistanceModel) sm).getScoreModel()
+ .getPairwiseScore('c', 'x'), 1f);
+
+ sm = models.next();
+ assertFalse(sm instanceof PairwiseDistanceModel);
+ assertEquals(sm.getName(), "Sequence Feature Similarity");
+
+ sm = models.next();
+ assertFalse(sm instanceof PairwiseDistanceModel);
+ assertEquals(sm.getName(), "PID");
+ }
+
+ /**
+ * 'Test' that prints out score matrices in tab-delimited format. This test is
+ * intentionally not assigned to any group so would not be run as part of a
+ * suite. It makes no assertions and is just provided as a utility method for
+ * printing out matrices. Relocated here from ScoreMatrixPrinter.
+ */
+ @Test
+ public void printAllMatrices_tabDelimited()
+ {
+ printAllMatrices(false);
+ }
+
+ /**
+ * 'Test' that prints out score matrices in html format. This test is
+ * intentionally not assigned to any group so would not be run as part of a
+ * suite. It makes no assertions and is just provided as a utility method for
+ * printing out matrices. Relocated here from ScoreMatrixPrinter.
+ */
+ @Test
+ public void printAllMatrices_asHtml()
+ {
+ printAllMatrices(true);
+ }
+
+ /**
+ * Print all registered ScoreMatrix as plain or html tables
+ *
+ * @param asHtml
+ */
+ protected void printAllMatrices(boolean asHtml)
+ {
+ for (DistanceModelI dm : ScoreModels.getInstance().getModels())
+ {
+ if (dm instanceof PairwiseDistanceModel)
+ {
+ PairwiseScoreModelI psm = ((PairwiseDistanceModel) dm)
+ .getScoreModel();
+ if (psm instanceof ScoreMatrix)
+ {
+ ScoreMatrix sm = (ScoreMatrix) psm;
+ System.out.println("ScoreMatrix " + sm.getName());
+ System.out.println(sm.outputMatrix(asHtml));
+ }
+ }
+ }
+ }
+}
{
"examples/testdata/cullpdb_pc25_res3.0_R0.3_d150729_chains9361.fasta.15316",
FileFormat.Fasta },
-
+ { "resources/scoreModel/pam250.scm", FileFormat.ScoreMatrix }
// { "examples/testdata/test.amsa", "AMSA" },
// { "examples/test.jnet", "JnetFile" },
};
--- /dev/null
+package jalview.io;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import jalview.analysis.scoremodels.ScoreMatrix;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+import org.testng.annotations.Test;
+
+public class ScoreMatrixFileTest
+{
+
+ /**
+ * Test a successful parse of a (small) score matrix file
+ *
+ * @throws IOException
+ * @throws MalformedURLException
+ */
+ @Test(groups = "Functional")
+ public void testParse() throws MalformedURLException, IOException
+ {
+ /*
+ * some messy but valid input data, with comma, space
+ * or tab (or combinations) as score value delimiters
+ * this example includes 'guide' symbols on score rows
+ */
+ String data = "ScoreMatrix MyTest (example)\n" + "ATU tx-\n"
+ + "A,1.1,1.2,1.3,1.4, 1.5, 1.6, 1.7\n"
+ + "T,2.1 2.2 2.3 2.4 2.5 2.6 2.7\n"
+ + "U\t3.1\t3.2\t3.3\t3.4\t3.5\t3.6\t3.7\n"
+ + " 4.1 ,4.2,\t,4.3 ,\t4.4\t, \4.5,4.6 4.7\n"
+ + "t, 5.1,5.3,5.3,5.4,5.5, 5.6, 5.7\n"
+ + "x\t6.1, 6.2 6.3 6.4 6.5 6.6 6.7\n"
+ + "-, \t7.1\t7.2 7.3, 7.4, 7.5\t,7.6,7.7\n";
+ FileParse fp = new FileParse(data, DataSourceType.PASTE);
+ ScoreMatrixFile parser = new ScoreMatrixFile(fp);
+ ScoreMatrix sm = parser.parseMatrix();
+
+ assertNotNull(sm);
+ assertEquals(sm.getName(), "MyTest (example)");
+ assertTrue(sm.isDNA());
+ assertFalse(sm.isProtein());
+ assertEquals(sm.getPairwiseScore('A', 'A'), 1.1f);
+ assertEquals(sm.getPairwiseScore('A', 'T'), 1.2f);
+ assertEquals(sm.getPairwiseScore('a', 'T'), 1.2f); // A/a equivalent
+ assertEquals(sm.getPairwiseScore('A', 't'), 1.5f); // T/t not equivalent
+ assertEquals(sm.getPairwiseScore('a', 't'), 1.5f);
+ assertEquals(sm.getPairwiseScore('T', ' '), 2.4f);
+ assertEquals(sm.getPairwiseScore('U', 'x'), 3.6f);
+ assertEquals(sm.getPairwiseScore('u', 'x'), 3.6f);
+ assertEquals(sm.getPairwiseScore('U', 'X'), 0f); // X (upper) unmapped
+ assertEquals(sm.getPairwiseScore('A', '.'), 0f); // . unmapped
+ assertEquals(sm.getPairwiseScore('-', '-'), 7.7f);
+ assertEquals(sm.getPairwiseScore('A', (char) 128), 0f); // out of range
+
+ /*
+ * without guide symbols on score rows
+ */
+ data = "ScoreMatrix MyTest\nXY\n1 2\n3 4\n";
+ fp = new FileParse(data, DataSourceType.PASTE);
+ parser = new ScoreMatrixFile(fp);
+ sm = parser.parseMatrix();
+ assertNotNull(sm);
+ assertEquals(sm.getPairwiseScore('X', 'X'), 1f);
+ assertEquals(sm.getPairwiseScore('X', 'y'), 2f);
+ assertEquals(sm.getPairwiseScore('y', 'x'), 3f);
+ assertEquals(sm.getPairwiseScore('y', 'Y'), 4f);
+ assertEquals(sm.getPairwiseScore('D', 'R'), 0f);
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_headerMissing()
+ {
+ String data;
+
+ data = "XY\n1 2\n3 4\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Format error: 'ScoreMatrix <name>' should be the first non-comment line");
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_notEnoughRows()
+ {
+ String data = "ScoreMatrix MyTest\nXY\n1 2\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Expected 2 rows of score data in score matrix but only found 1");
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_notEnoughColumns()
+ {
+ String data = "ScoreMatrix MyTest\nXY\n1 2\n3\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Expected 2 scores at line 4 but found 1");
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_tooManyColumns()
+ {
+ /*
+ * with two too many columns:
+ */
+ String data = "ScoreMatrix MyTest\nXY\n1 2\n3 4 5 6\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Expected 2 scores at line 4 but found 4");
+ }
+
+ /*
+ * with guide character and one too many columns:
+ */
+ data = "ScoreMatrix MyTest\nXY\nX 1 2\nY 3 4 5\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Expected 2 scores at line 4 but found 4");
+ }
+
+ /*
+ * with no guide character and one too many columns:
+ * parser guesses the first column is the guide character
+ */
+ data = "ScoreMatrix MyTest\nXY\n1 2\n3 4 5\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Error parsing score matrix at line 4, expected 'Y' but found '3'");
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_tooManyRows()
+ {
+ String data = "ScoreMatrix MyTest\nXY\n1 2\n3 4\n6 7";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Unexpected extra input line in score model file: '6 7'");
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_badDelimiter()
+ {
+ String data = "ScoreMatrix MyTest\nXY\n1|2\n3|4\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Expected 2 scores at line 3 but found 1");
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_badFloat()
+ {
+ String data = "ScoreMatrix MyTest\nXY\n1 2\n3 four\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Invalid score value 'four' at line 4 column 1");
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_badGuideCharacter()
+ {
+ String data = "ScoreMatrix MyTest\nXY\nX 1 2\ny 3 4\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Error parsing score matrix at line 4, expected 'Y' but found 'y'");
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_nameMissing()
+ {
+ /*
+ * Name missing
+ */
+ String data = "ScoreMatrix\nXY\n1 2\n3 4\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(
+ e.getMessage(),
+ "Format error: expected 'ScoreMatrix <name>', found 'ScoreMatrix' at line 1");
+ }
+ }
+}
+++ /dev/null
-/*
- * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
- * Copyright (C) $$Year-Rel$$ The Jalview Authors
- *
- * This file is part of Jalview.
- *
- * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *
- * Jalview 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
-package jalview.schemes;
-
-import jalview.api.analysis.ScoreModelI;
-import jalview.gui.JvOptionPane;
-
-import java.util.Map;
-
-import org.testng.annotations.BeforeClass;
-
-public class ScoreMatrixPrinter
-{
-
- @BeforeClass(alwaysRun = true)
- public void setUpJvOptionPane()
- {
- JvOptionPane.setInteractiveMode(false);
- JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
- }
-
- public void printAllMatrices()
- {
- for (Map.Entry<String, ScoreModelI> sm : ResidueProperties.scoreMatrices
- .entrySet())
- {
- System.out.println("Matrix " + sm.getKey());
- System.out.println(sm.getValue().toString());
- }
- }
-
- public void printHTMLMatrices()
- {
- for (Map.Entry<String, ScoreModelI> _sm : ResidueProperties.scoreMatrices
- .entrySet())
- {
- if (_sm.getValue() instanceof ScoreMatrix)
- {
- ScoreMatrix sm = (ScoreMatrix) _sm.getValue();
- System.out.println("Matrix " + _sm.getKey());
- System.out.println(sm.outputMatrix(true));
- }
- }
- }
-
-}
+++ /dev/null
-package jalview.schemes;
-
-import static org.testng.Assert.assertEquals;
-
-import jalview.math.MatrixI;
-
-import org.testng.annotations.Test;
-
-public class ScoreMatrixTest
-{
- @Test(groups = "Functional")
- public void testSymmetric()
- {
- verifySymmetric(ResidueProperties.getScoreMatrix("BLOSUM62"));
- verifySymmetric(ResidueProperties.getScoreMatrix("PAM250"));
- verifySymmetric(ResidueProperties.getScoreMatrix("DNA"));
- }
-
- private void verifySymmetric(ScoreMatrix sm)
- {
- int[][] m = sm.getMatrix();
- int rows = m.length;
- for (int row = 0; row < rows; row++)
- {
- assertEquals(m[row].length, rows);
- for (int col = 0; col < rows; col++)
- {
- assertEquals(m[row][col], m[col][row], String.format("%s [%s, %s]",
- sm.getName(), ResidueProperties.aa[row],
- ResidueProperties.aa[col]));
- }
- }
-
- /*
- * also check the score matrix is sized for
- * the number of symbols scored, plus gap
- */
- assertEquals(rows, (sm.isDNA() ? ResidueProperties.maxNucleotideIndex
- : ResidueProperties.maxProteinIndex) + 1);
- }
-
- /**
- * A test that just asserts the expected values in the Blosum62 score matrix
- */
- @Test(groups = "Functional")
- public void testBlosum62_values()
- {
- ScoreMatrix sm = ResidueProperties.getScoreMatrix("BLOSUM62");
-
- /*
- * verify expected scores against ARNDCQEGHILKMFPSTWYVBZX
- * scraped from https://www.ncbi.nlm.nih.gov/Class/FieldGuide/BLOSUM62.txt
- */
- verifyValues(sm, 'A', new int[] { 4, -1, -2, -2, 0, -1, -1, 0, -2, -1,
- -1, -1, -1, -2, -1, 1, 0, -3, -2, 0, -2, -1, 0 });
- verifyValues(sm, 'R', new int[] { -1, 5, 0, -2, -3, 1, 0, -2, 0, -3,
- -2, 2, -1, -3, -2, -1, -1, -3, -2, -3, -1, 0, -1 });
- verifyValues(sm, 'N', new int[] { -2, 0, 6, 1, -3, 0, 0, 0, 1, -3, -3,
- 0, -2, -3, -2, 1, 0, -4, -2, -3, 3, 0, -1 });
- verifyValues(sm, 'D', new int[] { -2, -2, 1, 6, -3, 0, 2, -1, -1, -3,
- -4, -1, -3, -3, -1, 0, -1, -4, -3, -3, 4, 1, -1 });
- verifyValues(sm, 'C', new int[] { 0, -3, -3, -3, 9, -3, -4, -3, -3, -1,
- -1, -3, -1, -2, -3, -1, -1, -2, -2, -1, -3, -3, -2 });
- verifyValues(sm, 'Q', new int[] { -1, 1, 0, 0, -3, 5, 2, -2, 0, -3, -2,
- 1, 0, -3, -1, 0, -1, -2, -1, -2, 0, 3, -1 });
- verifyValues(sm, 'E', new int[] { -1, 0, 0, 2, -4, 2, 5, -2, 0, -3, -3,
- 1, -2, -3, -1, 0, -1, -3, -2, -2, 1, 4, -1 });
- verifyValues(sm, 'G', new int[] { 0, -2, 0, -1, -3, -2, -2, 6, -2, -4,
- -4, -2, -3, -3, -2, 0, -2, -2, -3, -3, -1, -2, -1 });
- verifyValues(sm, 'H', new int[] { -2, 0, 1, -1, -3, 0, 0, -2, 8, -3,
- -3, -1, -2, -1, -2, -1, -2, -2, 2, -3, 0, 0, -1 });
- verifyValues(sm, 'I', new int[] { -1, -3, -3, -3, -1, -3, -3, -4, -3,
- 4, 2, -3, 1, 0, -3, -2, -1, -3, -1, 3, -3, -3, -1 });
- verifyValues(sm, 'L', new int[] { -1, -2, -3, -4, -1, -2, -3, -4, -3,
- 2, 4, -2, 2, 0, -3, -2, -1, -2, -1, 1, -4, -3, -1 });
- verifyValues(sm, 'K', new int[] { -1, 2, 0, -1, -3, 1, 1, -2, -1, -3,
- -2, 5, -1, -3, -1, 0, -1, -3, -2, -2, 0, 1, -1 });
- verifyValues(sm, 'M', new int[] { -1, -1, -2, -3, -1, 0, -2, -3, -2, 1,
- 2, -1, 5, 0, -2, -1, -1, -1, -1, 1, -3, -1, -1 });
- verifyValues(sm, 'F', new int[] { -2, -3, -3, -3, -2, -3, -3, -3, -1,
- 0, 0, -3, 0, 6, -4, -2, -2, 1, 3, -1, -3, -3, -1 });
- verifyValues(sm, 'P', new int[] { -1, -2, -2, -1, -3, -1, -1, -2, -2,
- -3, -3, -1, -2, -4, 7, -1, -1, -4, -3, -2, -2, -1, -2 });
- verifyValues(sm, 'S', new int[] { 1, -1, 1, 0, -1, 0, 0, 0, -1, -2, -2,
- 0, -1, -2, -1, 4, 1, -3, -2, -2, 0, 0, 0 });
- verifyValues(sm, 'T', new int[] { 0, -1, 0, -1, -1, -1, -1, -2, -2, -1,
- -1, -1, -1, -2, -1, 1, 5, -2, -2, 0, -1, -1, 0 });
- verifyValues(sm, 'W', new int[] { -3, -3, -4, -4, -2, -2, -3, -2, -2,
- -3, -2, -3, -1, 1, -4, -3, -2, 11, 2, -3, -4, -3, -2 });
- verifyValues(sm, 'Y', new int[] { -2, -2, -2, -3, -2, -1, -2, -3, 2,
- -1, -1, -2, -1, 3, -3, -2, -2, 2, 7, -1, -3, -2, -1 });
- verifyValues(sm, 'V', new int[] { 0, -3, -3, -3, -1, -2, -2, -3, -3, 3,
- 1, -2, 1, -1, -2, -2, 0, -3, -1, 4, -3, -2, -1 });
- verifyValues(sm, 'B', new int[] { -2, -1, 3, 4, -3, 0, 1, -1, 0, -3,
- -4, 0, -3, -3, -2, 0, -1, -4, -3, -3, 4, 1, -1 });
- verifyValues(sm, 'Z', new int[] { -1, 0, 0, 1, -3, 3, 4, -2, 0, -3, -3,
- 1, -1, -3, -1, 0, -1, -3, -2, -2, 1, 4, -1 });
- verifyValues(sm, 'X', new int[] { 0, -1, -1, -1, -2, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -2, 0, 0, -2, -1, -1, -1, -1, -1 });
- }
- /**
- * Helper method to check pairwise scores for one residue
- *
- * @param sm
- * @param res
- * @param expected
- * score values against 'res', in ResidueProperties.aaIndex order
- */
- private void verifyValues(ScoreMatrix sm, char res, int[] expected)
- {
- for (int j = 0; j < expected.length; j++)
- {
- char c2 = ResidueProperties.aa[j].charAt(0);
- assertEquals(sm.getPairwiseScore(res, c2), expected[j],
- String.format("%s->%s", res, c2));
- }
- }
-
- @Test(groups = "Functional")
- public void testComputePairwiseScores()
- {
- String[] seqs = new String[] { "FKL", "R-D", "QIA", "GWC" };
- ScoreMatrix sm = ResidueProperties.getScoreMatrix("BLOSUM62");
-
- MatrixI pairwise = sm.computePairwiseScores(seqs);
-
- /*
- * should be NxN where N = number of sequences
- */
- assertEquals(pairwise.height(), 4);
- assertEquals(pairwise.width(), 4);
-
- /*
- * should be symmetrical (because BLOSUM62 is)
- */
- for (int i = 0; i < pairwise.height(); i++)
- {
- for (int j = 0; j < pairwise.width(); j++)
- {
- assertEquals(pairwise.getValue(i, j), pairwise.getValue(j, i),
- "Not symmetric");
- }
- }
- /*
- * verify expected BLOSUM dot product scores
- */
- // F.F + K.K + L.L = 6 + 5 + 4 = 15
- assertEquals(pairwise.getValue(0, 0), 15d);
- // R.R + -.- + D.D = 5 + 1 + 6 = 12
- assertEquals(pairwise.getValue(1, 1), 12d);
- // Q.Q + I.I + A.A = 5 + 4 + 4 = 13
- assertEquals(pairwise.getValue(2, 2), 13d);
- // G.G + W.W + C.C = 6 + 11 + 9 = 26
- assertEquals(pairwise.getValue(3, 3), 26d);
- // F.R + K.- + L.D = -3 + -4 + -4 = -11
- assertEquals(pairwise.getValue(0, 1), -11d);
- // F.Q + K.I + L.A = -3 + -3 + -1 = -7
- assertEquals(pairwise.getValue(0, 2), -7d);
- // F.G + K.W + L.C = -3 + -3 + -1 = -7
- assertEquals(pairwise.getValue(0, 3), -7d);
- // R.Q + -.I + D.A = 1 + -4 + -2 = -5
- assertEquals(pairwise.getValue(1, 2), -5d);
- // R.G + -.W + D.C = -2 + -4 + -3 = -9
- assertEquals(pairwise.getValue(1, 3), -9d);
- // Q.G + I.W + A.C = -2 + -3 + 0 = -5
- assertEquals(pairwise.getValue(2, 3), -5d);
- }
-}
--- /dev/null
+package jalview.util;
+
+import static org.testng.Assert.assertEquals;
+
+import java.awt.Color;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.testng.annotations.Test;
+
+public class SetUtilsTest
+{
+ @Test(groups = "Functional")
+ public void testCountDisjunction()
+ {
+ Set<Color> s1 = new HashSet<Color>();
+ assertEquals(SetUtils.countDisjunction(null, null), 0);
+ assertEquals(SetUtils.countDisjunction(s1, null), 0);
+ assertEquals(SetUtils.countDisjunction(null, s1), 0);
+ s1.add(Color.white);
+ assertEquals(SetUtils.countDisjunction(s1, null), 1);
+ assertEquals(SetUtils.countDisjunction(null, s1), 1);
+ assertEquals(SetUtils.countDisjunction(s1, null), 1);
+ assertEquals(SetUtils.countDisjunction(s1, s1), 0);
+
+ Set<Object> s2 = new HashSet<Object>();
+ assertEquals(SetUtils.countDisjunction(s2, s2), 0);
+ assertEquals(SetUtils.countDisjunction(s1, s2), 1);
+ assertEquals(SetUtils.countDisjunction(s2, s1), 1);
+
+ s1.add(Color.yellow);
+ s1.add(Color.blue);
+ s2.add(new Color(Color.yellow.getRGB()));
+
+ /*
+ * now s1 is {white, yellow, blue}
+ * s2 is {yellow'}
+ */
+ assertEquals(SetUtils.countDisjunction(s1, s2), 2);
+ s2.add(Color.blue);
+ assertEquals(SetUtils.countDisjunction(s1, s2), 1);
+ s2.add(Color.pink);
+ assertEquals(SetUtils.countDisjunction(s1, s2), 2);
+
+ }
+}