From: gmungoc Date: Thu, 26 Mar 2015 11:14:54 +0000 (+0000) Subject: Merge develop to Release_2_8_3_Branch X-Git-Tag: Jalview_2_9~73^2 X-Git-Url: http://source.jalview.org/gitweb/?p=jalview.git;a=commitdiff_plain;h=be32c14cd8e48fe0a207cd7030cb9cd46f894678 Merge develop to Release_2_8_3_Branch --- diff --git a/.classpath b/.classpath index c110217..c19e381 100644 --- a/.classpath +++ b/.classpath @@ -51,10 +51,15 @@ - + + + + + + diff --git a/examples-jbake/templates/jvl_examples.ftl b/examples-jbake/templates/jvl_examples.ftl index ec5c684..d0e40bf 100644 --- a/examples-jbake/templates/jvl_examples.ftl +++ b/examples-jbake/templates/jvl_examples.ftl @@ -85,4 +85,20 @@ Try out JalviewLite by pressing one of the buttons below.
secondary structure annotation +

+

Linked amino acid and cDNA alignments for homologous proteins

+

+ + + + + +
<@jvlitebutton appjar="${content.jvl},${content.jmol}" params={ "permissions":"all-permissions" + , "file":"estrogenReceptorCdna.fa" + , "file2":"estrogenReceptorProtein.fa" + , "defaultColour":"Purine/Pyrimidine" + , "showAnnotation":"false" + , "windowHeight":"300" + , "windowWidth":"800" + , "showFullId":"false"} prots=true />Displays a split window view of protein and its related cDNA
diff --git a/examples/applets.html b/examples/applets.html index 9d94c69..b557efc 100755 --- a/examples/applets.html +++ b/examples/applets.html @@ -313,6 +313,29 @@ Try out JalviewLite by pressing one of the buttons below.
secondary structure annotation +

+

Linked amino acid and cDNA alignments for homologous proteins

+

+ + + + + +
+ + + + + + + + + + +Displays a split window view of protein and its related cDNA
diff --git a/examples/estrogenReceptorCdna.fa b/examples/estrogenReceptorCdna.fa new file mode 100644 index 0000000..9d857db --- /dev/null +++ b/examples/estrogenReceptorCdna.fa @@ -0,0 +1,221 @@ +>EMBLCDS|ADZ17331/1-1593 Homo sapiens (human) estrogen nuclear receptor beta variant a +atggatataaaaaactcaccatctagccttaattctccttcctcctacaactgcagtcaatccatcttaccc +ctggagcacggctccatatacataccttcctcctatgtagacagccaccatgaatatccagccatgacattc +tatagccctgctgtgatgaattacagcattcccagcaatgtcactaacttggaaggtgggcctggtcggcag +accacaagcccaaatgtgttgtggccaacacctgggcacctttctcctttagtggtccatcgccagttatca +catctgtatgcggaacctcaaaagagtccctggtgtgaagcaagatcgctagaacacaccttacctgtaaac +agagagacactgaaaaggaaggttagtgggaaccgttgcgccagccctgttactggtccaggttcaaagagg +gatgctcacttctgcgctgtctgcagcgattacgcatcgggatatcactatggagtctggtcgtgtgaagga +tgtaaggccttttttaaaagaagcattcaaggacataatgattatatttgtccagctacaaatcagtgtaca +atcgataaaaaccggcgcaagagctgccaggcctgccgacttcggaagtgttacgaagtgggaatggtgaag +tgtggctcccggagagagagatgtgggtaccgccttgtgcggagacagagaagtgccgacgagcagctgcac +tgtgccggcaaggccaagagaagtggcggccacgcgccccgagtgcgggagctgctgctggacgccctgagc +cccgagcagctagtgctcaccctcctggaggctgagccgccccatgtgctgatcagccgccccagtgcgccc +ttcaccgaggcctccatgatgatgtccctgaccaagttggccgacaaggagttggtacacatgatcagctgg +gccaagaagattcccggctttgtggagctcagcctgttcgaccaagtgcggctcttggagagctgttggatg +gaggtgttaatgatggggctgatgtggcgctcaattgaccaccccggcaagctcatctttgctccagatctt +gttctggacagggatgaggggaaatgcgtagaaggaattctggaaatctttgacatgctcctggcaactact +tcaaggtttcgagagttaaaactccaacacaaagaatatctctgtgtcaaggccatgatcctgctcaattcc +agtatgtaccctctggtcacagcgacccaggatgctgacagcagccggaagctggctcacttgctgaacgcc +gtgaccgatgctttggtttgggtgattgccaagagcggcatctcctcccagcagcaatccatgcgcctggct +aacctcctgatgctcctgtcccacgtcaggcatgcgagtaacaagggcatggaacatctgctcaacatgaag +tgcaaaaatgtggtcccagtgtatgacctgctgctggagatgctgaatgcccacgtgcttcgcgggtgcaag +tcctccatcacggggtccgagtgcagcccggcagaggacagtaaaagcaaagagggctcccagaacccacag +tctcagtga +>EMBLCDS|AAK93056/1-1455 Drosophila melanogaster (fruit fly) GH28308p +atgtccgacggcgtcagcatcttgcacatcaaacaggaggtggacactccatcggcgtcctgctttagtccc +agctccaagtcaacggccacgcagagtggcacaaacggcctgaaatcctcgccctcggtttcgccggaaagg +cagctctgcagctcgacgacctctctatcctgcgatttgcacaatgtatccttaagcaatgatggcgatagt +ctgaaaggaagtggtacaagtggcggcaatggcggaggaggaggtggtggtacgagtggtggaaatgcgacc +aatgcgagtgccggagctggatcgggatccgtcagggacgagctccgccgattgtgtttggtttgtggcgat +gtggccagtggattccactatggtgtggcgagttgtgaggcttgcaaagcgttctttaaacgcaccatccaa +ggcaacatcgagtacacgtgtccggcgaacaacgagtgtgagattaacaagcggagacgcaaggcctgccaa +gcgtgtcgcttccagaaatgtctactaatgggcatgctcaaggagggtgtgcgcttggatcgagttcgtgga +ggacggcagaagtaccgaaggaatcctgtatcaaactcttaccagactatgcagctgctataccaatccaac +accacctcgctgtgcgatgtcaagatactggaggtgctcaattcatatgagccggatgccttgagcgtccaa +acgccgccgccgcaagtccacacgactagcataactaatgatgaggcctcatcctcctcgggcagcataaaa +ctggagtccagcgttgttacgcccaatgggacttgcattttccaaaacaacaacaacaatgatcccaatgag +atactaagcgtccttagtgatatttacgacaaggaattggtcagcgtcattggctgggccaagcagatacct +ggctttatagatctgccacttaacgaccagatgaagcttctccaggtgtcgtgggcagagatcctgacgctc +cagctgaccttccggtccctaccgttcaatggcaagttatgcttcgccacggatgtctggatggatgaacat +ttggccaaggagtgcggttacacggagttctactaccactgcgtccagatcgcacagcgcatggaaagaata +tcgccacgaagggaggagtactacttgctaaaggcgctcctgctggccaactgcgacattctgctggatgat +cagagttccctgcgcgcatttcgtgatacgattcttaattctctaaacgatgtggtctacttgctgcgtcat +tcgtcggccgtgtcgcatcagcaacaattgctgcttttgctgccttcgctgcggcaggcggatgatatcctg +cgaagattttggcgtggaattgcacgcgatgaagtcattaccatgaagaaactgttcctcgagatgctcgag +ccgctggccaggtga +>EMBLCDS|BAA89539/1-2133 Anguilla japonica (Japanese eel) progesterone receptor +atggacaacaatcaccaagacaagatggaaagtctatacacgccagccagagcatcaccaactcctgatgca +gaatcgattaaaagagccaggaatttgattaaaacatactcggagtcttttgggagttatgtggaggagata +gttcgagacgactcgaataacatacaatctttgagcagcgtccctctcttgatgcgtaattttggaaacatg +gacaccctaacctgcgcacctggctcgggtagtgacagtgagatttggaaagactttgttgttcccgggaac +tctgtggtaagcaaagacacctgtggtcatgttgaaatatccactaaagccgaaaatttgtcttgggctgcc +gcgcccttaagtagagaagaaaccctcgcgaaaggaactgttacggtcccagcgactgtgcctaaagaaagt +tttaccgcaacatcaaacacttcttcagccagtggaatctctattaaagatgaacaacaatctttgctcaaa +atggaaccacagtcttctgacttttgtccttatacagcaaatataccgaaattgaatccatcttatctgacc +aatactgcgagtacgaaacaacttggatatggcgaacagccggacacttcagcgcactcctctccacctgct +cagaagattgttttagatactgctcgatactcggccgatttatgttcggataaccctttaccgcaagcgaca +aatatcaaaacagatccttgtagtagtttctcttctttcgttggagaagggatccttactagggcatctatg +ggctactcacagcaagcgattcagacattgccggtgcacaagagtgaaccgttcaggttgtctgcttcgagc +gcgcccgcggattctccgttttggtgccaatccacgggtccttctgaggatcatcatctgcagattgactat +ctatctcccgctggactccacagcacatgcaaatacagttccacgaacgcgtacagctcctatttaggtgtg +ctgccccagagggtgtgcgtcatctgtggggatgaagcatcaggctgtcactatggtgtcctcacctgtggc +agctgtaaggtgttctttaagagggcagtggaaggccatcataactacttgtgtgctggacggaatgactgc +atcgtggacaagatccgtaggaaaaactgtcctgcttgtcgcctcagaaagtgctaccaggcgggaatgata +ctgggaggtcggaagctgaagaagttgggggctctgaaggcagcagggctgacccaggccctggtggcccac +tcactgactcctcggaggctctctggtgacagccaggccctgatgcccctgggctgccttccaggggtccgg +gagctgcacctttccccacagatcatcagcgtgctggagagcattgagcctgaggtggtgtactctggttat +gacaactcccagcctgacatgcccaatatgctgctcaacagcctcaaccgcttatgtgagaggcagctgctg +aggattgtcaagtggtccaagtctttaccaggttttcgcagtttacacatcaatgaccaaatggctctgatc +cagtactcctggatgagcttaatggtattttctttgggttggcggtctttccaaaatgtcaccagtgattac +ctgtactttgcacctgacctcattctcaacgaagagtatatgaggaggtctccaatatttgacctgtgcatg +gccatgcagttcatccctcaagagtttgccaatctccaggtgaccaaggaggagtttctgtgcatgaaggtc +ttgctgttgctcaacacagtgcctctggaggggttgaagagccagccacagtttgatgagatgaggcagaat +tacatccatgaactcaccaaggccattcacctgcgagagaatggtgtggtcgcctgctcccagcgtttctac +cacctgaccaagctgatggaccacatgcatgacattgtgaagaagctccacctgtactgcctgagcactttc +attcaggcagatgccatgcgggtagagttccccgagatgatgtcagaagtcatcgcctcccagctgcctcgg +gtgctcgctggaatggtgaaaccccttctttttcacaccaaatga +>EMBLCDS|AHW56473/1-1590 Homo sapiens (human) partial estrogen receptor 2 isoform A +atggatataaaaaactcaccatctagccttaattctccttcctcctacaactgcagtcaatccatcttaccc +ctggagcacggctccatatacataccttcctcctatgtagacagccaccatgaatatccagccatgacattc +tatagccctgctgtgatgaattacagcattcccagcaatgtcactaacttggaaggtgggcctggtcggcag +accacaagcccaaatgtgttgtggccaacacctgggcacctttctcctttagtggtccatcgccagttatca +catctgtatgcggaacctcaaaagagtccctggtgtgaagcaagatcgctagaacacaccttacctgtaaac +agagagacactgaaaaggaaggttagtgggaaccgttgcgccagccctgttactggtccaggttcaaagagg +gatgctcacttctgcgctgtctgcagcgattacgcatcgggatatcactatggagtctggtcgtgtgaagga +tgtaaggccttttttaaaagaagcattcaaggacataatgattatatttgtccagctacaaatcagtgtaca +atcgataaaaaccggcgcaagagctgccaggcctgccgacttcggaagtgttacgaagtgggaatggtgaag +tgtggctcccggagagagagatgtgggtaccgccttgtgcggagacagagaagtgccgacgagcagctgcac +tgtgccggcaaggccaagagaagtggcggccacgcgccccgagtgcgggagctgctgctggacgccctgagc +cccgagcagctagtgctcaccctcctggaggctgagccgccccatgtgctgatcagccgccccagtgcgccc +ttcaccgaggcctccatgatgatgtccctgaccaagttggccgacaaggagttggtacacatgatcagctgg +gccaagaagattcccggctttgtggagctcagcctgttcgaccaagtgcggctcttggagagctgttggatg +gaggtgttaatgatggggctgatgtggcgctcaattgaccaccccggcaagctcatctttgctccagatctt +gttctggacagggatgaggggaaatgcgtagaaggaattctggaaatctttgacatgctcctggcaactact +tcaaggtttcgagagttaaaactccaacacaaagaatatctctgtgtcaaggccatgatcctgctcaattcc +agtatgtaccctctggtcacagcgacccaggatgctgacagcagccggaagctggctcacttgctgaacgcc +gtgaccgatgctttggtttgggtgattgccaagagcggcatctcctcccagcagcaatccatgcgcctggct +aacctcctgatgctcctgtcccacgtcaggcatgcgagtaacaagggcatggaacatctgctcaacatgaag +tgcaaaaatgtggtcccagtgtatgacctgctgctggagatgctgaatgcccacgtgcttcgcgggtgcaag +tcctccatcacggggtccgagtgcagcccggcagaggacagtaaaagcaaagagggctcccagaacccacag +tctcag +>EMBLCDS|BAA75464/1-2547 Anguilla japonica (Japanese eel) androgen receptor alpha +atggagattccagttgggttaggaggagtttcagatgccacaaacgccgtttttcgcggaccttaccaaaac +gttttccacagccttcaagtggcatttcagagtcacggtgccgtctccaggagcttagattttccaaataca +aagtacggttttttacaaaacagacatttctgtgaaatgcgtcaggagaacaagcagccgccatgcaaagga +ctcggcctattttacgggaaccatcgtaattcggacactgggacaaacgaagacgacatcgcttgtttttcc +agacagtccgacgctgaagccagacctggtattttttctgaaagctcattggatactggagacgagattact +tgcaaactccagtcagacaaccaaggggtaagagcgagcggtcctctcctaccgggctctagcggctgcaat +tcgggacaaaagtcctcccttgcttgtacgtcccaacaaagggagacaacatctcaaagtgacacctgcgca +ggagagagctgctcggaacatcaagcaactaccatttcggaaactgcgcgcgaattgtgcaacgccgtttcc +gtgtcgctgggcttgaatttagatcttaatgatatgaatgacctaagttcaaaccaaatatcgtctaccgaa +agtgacacaagtcaagccatctacttatttgaatcttcacctgggtatactggggtcggactgaacgccttg +gtaagagactgtaaatgtcagagtgcacgcgaagggacatcgacacaacagtacgaccgcggggcaatgttt +aagataaaccgtgtaaatgacttgccgcttcagccagcacccccgcgacacaccagcattagcgatgctaaa +tgggacatggaagcaggtttgtgtgcgcagatggagcacaaagactctgaaaagtgcgcgaatatggatggt +gcacactccacttctgtcttctcccagttcgaccaactgttgccagtaaacgcgtcgcactacagtcagaac +gtttcggtcagagtggaaccacaaagtgatttctctccgattttgtacaaatcacctggtattcagaaaaat +gccgaaaagtacaatgtccaatatgatgccacaattaaatcagaagatgggaaaacgacatctgaacgggaa +tggggttttcagtacaggtacaatgaaagctgcagcacaccgtcagcacctcctagacattgtgcacatcag +aacagggccggaccgtacaaccagttcttttttaatccatttgaatatgcgaaaagaggtgttgtctcaagg +gaaggatattctctcgaacatgggttcccaaacaatctcgctcggacaccctactctggttccttgaaaaac +gaactaggagatcgtctgagtgggccataccctgacgtcagttacaggtacgagggcgagcgggagaacgtg +ttccccgtggagttcttctttccgccgcagaggacctgcctgatctgcggggacgaggcctcgggctgtcac +tatggagccctcacctgcggcagctgcaaggtgttcttcaagagggccgcggaagggaaacagaagtacctg +tgcgccagcatcaatgattgcaccattgataaacttcgaaggaagaactgcccctcttgccgtctcaaaagg +tgctttgctgccggaatgacccttggagcgcggaagctgaagaagatcgggcaaatgagggcccccgaggat +ggccaggggcagggcccggcggaagcggagctgagcgtctcccccaagtacgacctgggcttccacacccag +tccatgttcctcaacatcctggaggccatcgagccggaggtggtgaacgccgggcacgactatggccagccg +gactctgcggccagcctgctgaccagcctcaacgagctcggagaacggcaactcgtcaaggtcgtcaagtgg +gccaagggcatgccaggttttcggagtctgtacgtggatgaccagatgacagtcatccagcactcctggatg +gcagtgatggtgttcgctctgggctggaggtcatttaagaatgtgaagtccaggatgctttactttgctcct +gaccttgttttcaacgagcaccgaatgcaggtgtccaccatgtatgaacactgcatccggatgaagaacttc +tcccaggagtttgctatgctgcaggtctcccaggaagagttcctgtgcatgaaagctctgcttctcttcagc +accatccccgttgaagggctgaaggggcagaatttctttgacgagctgcggaggagctacattaacgagctg +gaccggctggttagcttcaggagcaagtccagctgttccgagaggttccagcagctcacccgcctcctggac +tccctccaacctgttctgaagaagctccaccagtttacgttcgaccttttcgtccagtcccagaacctctcc +aaccaagtttgctttcccgagatgatctcagagatcatatccgtgcacgtgccaaagattctcgctggcacg +gtgaagccaatcctcttccacaagtag +>EMBLCDS|AAK20930/1-1317 Petromyzon marinus (sea lamprey) partial corticoid receptor +ggggtggagtttcagttgccctactcggcatctgccacatcctttcgtccgtccgttgccacctcgtccgcc +tcgggcatctccaacttttcaaatgggaataattttggattcctttctcccaatggagtacaacaggatgga +tttccttaccctggtttcacgagtcccgcacagtcctcagtccctccgcagaaggcgtgtctcatctgtagt +gatgaggcttcgggctgccactacggagtgctcacctgtggaagctgcaaggtgttcttcaagcgtgccgtg +gaaggacagcacaattatctgtgcgccggacgaaacgactgcatcattgacaagatccgccgcaagaactgc +ccagcttgccgtctgcgcaagtgcatccaggctggaatgacgctaggagcacgcaagcttaagaagcaaggc +cgggtaaagggagagaaccagcgcagcccagcgtcctccacagccaccacctcgtctgccaccccgcaaccc +tccagcaactcgacggccgtgaccacgttctcgccaccgccgaccggagagcccattttctcacccacactc +atcgccatcctgcaggcgatcgagcccgaggtggtcatgtccggctatgacaacacgcggtcccagaccacc +gcctacatgctgtcgagcctcaaccgcctctgcgacaagcagctcgtgtccattgtcaagtgggccaagtct +ctgccaggtttccgaaacctgcacatcgacgaccagatggtgttaatccagtactcatggatgggcctgatg +tcatttgccatgagctggaggtccttccagcacaccaacagcaagctgctctactttgctcctgatctggtt +tttgatgagacgcgcatgcagcartcggcgatgtatcaattgtgcgtggaaatgaggcaagtctcggaggac +ttcatgaagttgcaagtcacttcagaggagtttctgtgcatgaaagccatcttgctcctgagtactgtccca +caagagggtctgaagagccagggctgcttcgaggagatgcggatcagctacatccgggaattgaaccggacc +atcgcgcggacggagaagaatgccgtgcagtgttggcagcgcttctaccagctcaccaagctgctggrctgc +atgcaggatctcgtgagcaagctcctggagttctgcttcgcaaccttcacgcagacgcaggtgtggagtgtg +gagtttcctgacatgatggccgagatcatcagtgcgcagcttgcctcgcatcatggccgagaagcccgggca +ctccacttccacaagaaatga +>EMBLCDS|AAA17402/1-1032 Serinus canaria (common canary) partial androgen receptor +gaagcctccgggtgccactacggagccctgacgtgtgggagctgcaaagtgttcttcaaacgggcagctgaa +ggtaaacagaagtacctctgtgccagccgcaacgactgcaccatcgacaagttccggcggaaaaactgcccc +tcctgccgcctgcgcaagtgctacgaggccgggatgacgcttggagcccgcaagctgaagaaactgggtaac +ctgaaggcacaggacgacatagagggagccagctcgtccagcccaacggaggagcaagctcccaagctggtg +atgacacgcattgatggctacgagtgccagcccatcttcctcaacgtcctggaggccatcgagcctggggtg +gtgtgtgctggccatgacaacagccagcctgactccttctccaacctgctgaccagcctgaatgagcttggg +gagaggcagctggtctacgtggtcaaatgggcaaaggctctgccaggatttcgcaacctgcatgtggatgac +cagatgtcaataatccagtactcttggatgggcctgatggtgtttgctatggggtggagatccttcaccaac +gtcaattccaggatgctttactttgctccagacctggtcttcaatgagtaccgcatgcacaaatccaggatg +tacagccagtgcatcaggatgcggcacctctcccaggaattcgggtggcttcagatcacaccccaggggttc +ctctgtatgaaggctctcctcttcttcagtattattccagtggatggcctgaagaaccagaagctcttcgat +gagctccgcatgaattacatcaaggaacttgaccgtatcattgcctgcaagaggaagaaccccacctcatgc +tcccggaggttttaccagctcaccaaggtcctggactccgtgactccgattgccaaggacctgcatcagttt +acatttgatctcctaatcaaggcacacatggtgagcgtggactacccagaaatgatggctgagatcatctct +gtgcaggttcccaagatcctgtct +>EMBLCDS|AAL37553/1-1455 Drosophila melanogaster (fruit fly) estrogen-related receptor +atgtccgacggcgtcagcatcttgcacatcaaacaggaggtggacactccatcggcgtcctgctttagtccc +agctccaagtcaacggccacgcagagtggcacaaacggcctgaaatcctcgccctcggtttcgccggaaagg +cagctctgcagctcgacgacctctctatcctgcgatttgcacaatgtatccttaagcaatgatggcgatagt +ctgaaaggaagtggtacaagtggcggcaatggcggaggaggaggtggtggtacgagtggtggaaatgcgacc +aatgcgagtgccggagctggatcgggatccgtcagggacgagctccgccgattgtgtttggtttgtggcgat +gtggccagtggattccactatggtgtggcgagttgtgaggcttgcaaagcgttctttaaacgcaccatccaa +ggcaacatcgagtacacgtgtccggcgaacaacgagtgtgagattaacaagcggagacgcaaggcctgccaa +gcgtgtcgcttccagaaatgtctactaatgggcatgctcaaggagggtgtgcgcttggatcgagttcgtgga +ggacggcagaagtaccgaaggaatcctgtatcaaactcttaccagactatgcagctgctataccaatccaac +accacctcgctgtgcgatgtcaagatactggaggtgctcaattcatatgagccggatgccttgagcgtccaa +acgccgccgccgcaagtccacacgactagcataactaatgatgaggcctcatcctcctcgggcagcataaaa +ctggagtccagcgttgttacgcccaatgggacttgcattttccaaaacaacaacaacaatgatcccaatgag +atactaagcgtccttagtgatatttacgacaaggaattggtcagcgtcattggctgggccaagcagatacct +ggctttatagatctgccacttaacgaccagatgaagcttctccaggtgtcgtgggcagagatcctgacgctc +cagctgaccttccggtccctaccgttcaatggcaagttatgcttcgccacggatgtctggatggatgaacat +ttggccaaggagtgcggttacacggagttctactaccactgcgtccagatcgcacagcgcatggaaagaata +tcgccacgaagggaggagtactacttgctaaaggcgctcctgctggccaactgcgacattctgctggatgat +cagagttccctgcgcgcatttcgtgatacgattcttaattctctaaacgatgtggtctacttgctgcgtcat +tcgtcggccgtgtcgcatcagcaacaattgctgcttttgctgccttcgctgcggcaggcggatgatatcctg +cgaagattttggcgtggaattgcacgcgatgaagtcattaccatgaagaaactgttcctcgagatgctcgag +ccgctggccaggtga +>EMBLCDS|AAK20929/1-1662 Petromyzon marinus (sea lamprey) partial estrogen receptor +gcacgaggcttcagcgaggcacatggctacgagtactccggggcctcgctctaccagccactgcctccctcg +tgcacagagttctcaattggagctcatcaacaacaacaacatcagcaccagcatcaccagcaccagcatcag +cagcaccaccaccagcagcagcagcagcagccacagccgcagcagaatggagttttgggcgaggggcagagt +tcccatctctcttatcttccgccctcgaccgagctgccccagtacgtgccctccagccccagcgcgccctac +agcatggagctcggggcagggcgtcctcacggctacgacccagggccacagagcctctacaggggcggtgtg +gagagcagcgcccccccgtacagcgagcagcagcaggtggtgggcggcggcggagccatgtcggccatgggc +ttgacagagccacgccacgtcagctccggatcgctacccagcagcacgaggcccgagcgcagcacccagttc +tgtgccgtgtgcagcgactatgcctcggggtaccactacggcgtgtggtcctgcgagggctgcaaagccttc +ttcaagcgcagcacgcaaggccacaatgactacatgtgcccggccaccaaccagtgcaccatcgacaggaac +cgtcgcaagagctgtcaggcttgccgcctgcgtaagtgctacgaagtgggcatggtcaaaggcgttcgcaag +gaccgcaaaggctttcgaggggtcaagcacaaacgtaagcgccccatcccccaaaagaatgggggagaagga +ggtgccggcggcggccaagacgtgagcgagacgaggcctcagggtgagaggccctccgggccgagggaccgg +gagagcgccgtcagctcactcgaggctgaccaggtgatctcggctcttctggaggctgagccacccaccgta +ctgtcctcgtatgaccccgacaagcctgtgacggaggcctcgctcatggctgctctcaccagcctggctgac +cgagagctcgtgcacatgatcacctgggctaagaagattccaggattcacggccatcgggctgagtgaccag +gtgcagctgctggagtgctgctggctggagatcctaatcgtggggctcatctggaggtctatcgatcgccct +ggtcagctccactttgctccaaacctcatcctaggaagggaggacgcgcgcaatgtggagggcatgctggac +atgttcgacatgctgctcgtcaccgtgagtcgcttccgtgagctgcatctccgccgggaggaatacgtctgc +ctcaaggccatgatcctcctcaactcgggggtgtttttctgcctctccaattccgccggggagcagacgaat +gtgcagctcatccagcagatcctcgagaaggtgatggacgccctgggcagcaccatcggccacattgaggcg +tccccgccgcaacactcgcgtcgcctctcccagctgctcctgctgctttcacagatccggcacattagcaac +aagggcatcgagcatctcaacagcatgaagcgtaagaatgtgatcccgctatacgacctgctccttgagctg +ctggacgctcacagcctgcagaatactggcttacggacgtcgcccccaccgcaggatttcagggcaaccctc +gtgccg diff --git a/examples/estrogenReceptorProtein.fa b/examples/estrogenReceptorProtein.fa new file mode 100644 index 0000000..0541d39 --- /dev/null +++ b/examples/estrogenReceptorProtein.fa @@ -0,0 +1,81 @@ +>UNIPROT|Q7LCB3/1-530 estrogen nuclear receptor beta variant a +MDIKNSPSSLNSPSSYNCSQSILPLEHGSIYIPSSYVDSHHEYPAMTFYSPAVMNYSIPSNVTNLEGGPGRQ +TTSPNVLWPTPGHLSPLVVHRQLSHLYAEPQKSPWCEARSLEHTLPVNRETLKRKVSGNRCASPVTGPGSKR +DAHFCAVCSDYASGYHYGVWSCEGCKAFFKRSIQGHNDYICPATNQCTIDKNRRKSCQACRLRKCYEVGMVK +CGSRRERCGYRLVRRQRSADEQLHCAGKAKRSGGHAPRVRELLLDALSPEQLVLTLLEAEPPHVLISRPSAP +FTEASMMMSLTKLADKELVHMISWAKKIPGFVELSLFDQVRLLESCWMEVLMMGLMWRSIDHPGKLIFAPDL +VLDRDEGKCVEGILEIFDMLLATTSRFRELKLQHKEYLCVKAMILLNSSMYPLVTATQDADSSRKLAHLLNA +VTDALVWVIAKSGISSQQQSMRLANLLMLLSHVRHASNKGMEHLLNMKCKNVVPVYDLLLEMLNAHVLRGCK +SSITGSECSPAEDSKSKEGSQNPQSQ +>UNIPROT|Q9VSE9/1-484 GH28308p +MSDGVSILHIKQEVDTPSASCFSPSSKSTATQSGTNGLKSSPSVSPERQLCSSTTSLSCDLHNVSLSNDGDS +LKGSGTSGGNGGGGGGGTSGGNATNASAGAGSGSVRDELRRLCLVCGDVASGFHYGVASCEACKAFFKRTIQ +GNIEYTCPANNECEINKRRRKACQACRFQKCLLMGMLKEGVRLDRVRGGRQKYRRNPVSNSYQTMQLLYQSN +TTSLCDVKILEVLNSYEPDALSVQTPPPQVHTTSITNDEASSSSGSIKLESSVVTPNGTCIFQNNNNNDPNE +ILSVLSDIYDKELVSVIGWAKQIPGFIDLPLNDQMKLLQVSWAEILTLQLTFRSLPFNGKLCFATDVWMDEH +LAKECGYTEFYYHCVQIAQRMERISPRREEYYLLKALLLANCDILLDDQSSLRAFRDTILNSLNDVVYLLRH +SSAVSHQQQLLLLLPSLRQADDILRRFWRGIARDEVITMKKLFLEMLEPLAR +>UNIPROT|Q9IBD5/1-710 progesterone receptor +MDNNHQDKMESLYTPARASPTPDAESIKRARNLIKTYSESFGSYVEEIVRDDSNNIQSLSSVPLLMRNFGNM +DTLTCAPGSGSDSEIWKDFVVPGNSVVSKDTCGHVEISTKAENLSWAAAPLSREETLAKGTVTVPATVPKES +FTATSNTSSASGISIKDEQQSLLKMEPQSSDFCPYTANIPKLNPSYLTNTASTKQLGYGEQPDTSAHSSPPA +QKIVLDTARYSADLCSDNPLPQATNIKTDPCSSFSSFVGEGILTRASMGYSQQAIQTLPVHKSEPFRLSASS +APADSPFWCQSTGPSEDHHLQIDYLSPAGLHSTCKYSSTNAYSSYLGVLPQRVCVICGDEASGCHYGVLTCG +SCKVFFKRAVEGHHNYLCAGRNDCIVDKIRRKNCPACRLRKCYQAGMILGGRKLKKLGALKAAGLTQALVAH +SLTPRRLSGDSQALMPLGCLPGVRELHLSPQIISVLESIEPEVVYSGYDNSQPDMPNMLLNSLNRLCERQLL +RIVKWSKSLPGFRSLHINDQMALIQYSWMSLMVFSLGWRSFQNVTSDYLYFAPDLILNEEYMRRSPIFDLCM +AMQFIPQEFANLQVTKEEFLCMKVLLLLNTVPLEGLKSQPQFDEMRQNYIHELTKAIHLRENGVVACSQRFY +HLTKLMDHMHDIVKKLHLYCLSTFIQADAMRVEFPEMMSEVIASQLPRVLAGMVKPLLFHTK +>UNIPROT|Q7LCB3/1-530 estrogen receptor 2 isoform A +MDIKNSPSSLNSPSSYNCSQSILPLEHGSIYIPSSYVDSHHEYPAMTFYSPAVMNYSIPSNVTNLEGGPGRQ +TTSPNVLWPTPGHLSPLVVHRQLSHLYAEPQKSPWCEARSLEHTLPVNRETLKRKVSGNRCASPVTGPGSKR +DAHFCAVCSDYASGYHYGVWSCEGCKAFFKRSIQGHNDYICPATNQCTIDKNRRKSCQACRLRKCYEVGMVK +CGSRRERCGYRLVRRQRSADEQLHCAGKAKRSGGHAPRVRELLLDALSPEQLVLTLLEAEPPHVLISRPSAP +FTEASMMMSLTKLADKELVHMISWAKKIPGFVELSLFDQVRLLESCWMEVLMMGLMWRSIDHPGKLIFAPDL +VLDRDEGKCVEGILEIFDMLLATTSRFRELKLQHKEYLCVKAMILLNSSMYPLVTATQDADSSRKLAHLLNA +VTDALVWVIAKSGISSQQQSMRLANLLMLLSHVRHASNKGMEHLLNMKCKNVVPVYDLLLEMLNAHVLRGCK +SSITGSECSPAEDSKSKEGSQNPQSQ +>UNIPROT|Q9YGV9/1-848 androgen receptor alpha +MEIPVGLGGVSDATNAVFRGPYQNVFHSLQVAFQSHGAVSRSLDFPNTKYGFLQNRHFCEMRQENKQPPCKG +LGLFYGNHRNSDTGTNEDDIACFSRQSDAEARPGIFSESSLDTGDEITCKLQSDNQGVRASGPLLPGSSGCN +SGQKSSLACTSQQRETTSQSDTCAGESCSEHQATTISETARELCNAVSVSLGLNLDLNDMNDLSSNQISSTE +SDTSQAIYLFESSPGYTGVGLNALVRDCKCQSAREGTSTQQYDRGAMFKINRVNDLPLQPAPPRHTSISDAK +WDMEAGLCAQMEHKDSEKCANMDGAHSTSVFSQFDQLLPVNASHYSQNVSVRVEPQSDFSPILYKSPGIQKN +AEKYNVQYDATIKSEDGKTTSEREWGFQYRYNESCSTPSAPPRHCAHQNRAGPYNQFFFNPFEYAKRGVVSR +EGYSLEHGFPNNLARTPYSGSLKNELGDRLSGPYPDVSYRYEGERENVFPVEFFFPPQRTCLICGDEASGCH +YGALTCGSCKVFFKRAAEGKQKYLCASINDCTIDKLRRKNCPSCRLKRCFAAGMTLGARKLKKIGQMRAPED +GQGQGPAEAELSVSPKYDLGFHTQSMFLNILEAIEPEVVNAGHDYGQPDSAASLLTSLNELGERQLVKVVKW +AKGMPGFRSLYVDDQMTVIQHSWMAVMVFALGWRSFKNVKSRMLYFAPDLVFNEHRMQVSTMYEHCIRMKNF +SQEFAMLQVSQEEFLCMKALLLFSTIPVEGLKGQNFFDELRRSYINELDRLVSFRSKSSCSERFQQLTRLLD +SLQPVLKKLHQFTFDLFVQSQNLSNQVCFPEMISEIISVHVPKILAGTVKPILFHK +>UNIPROT|Q90ZM7/1-438 corticoid receptor +GVEFQLPYSASATSFRPSVATSSASGISNFSNGNNFGFLSPNGVQQDGFPYPGFTSPAQSSVPPQKACLICS +DEASGCHYGVLTCGSCKVFFKRAVEGQHNYLCAGRNDCIIDKIRRKNCPACRLRKCIQAGMTLGARKLKKQG +RVKGENQRSPASSTATTSSATPQPSSNSTAVTTFSPPPTGEPIFSPTLIAILQAIEPEVVMSGYDNTRSQTT +AYMLSSLNRLCDKQLVSIVKWAKSLPGFRNLHIDDQMVLIQYSWMGLMSFAMSWRSFQHTNSKLLYFAPDLV +FDETRMQQSAMYQLCVEMRQVSEDFMKLQVTSEEFLCMKAILLLSTVPQEGLKSQGCFEEMRISYIRELNRT +IARTEKNAVQCWQRFYQLTKLLXCMQDLVSKLLEFCFATFTQTQVWSVEFPDMMAEIISAQLASHHGREARA +LHFHKK +>UNIPROT|Q91445/1-344 androgen receptor +EASGCHYGALTCGSCKVFFKRAAEGKQKYLCASRNDCTIDKFRRKNCPSCRLRKCYEAGMTLGARKLKKLGN +LKAQDDIEGASSSSPTEEQAPKLVMTRIDGYECQPIFLNVLEAIEPGVVCAGHDNSQPDSFSNLLTSLNELG +ERQLVYVVKWAKALPGFRNLHVDDQMSIIQYSWMGLMVFAMGWRSFTNVNSRMLYFAPDLVFNEYRMHKSRM +YSQCIRMRHLSQEFGWLQITPQGFLCMKALLFFSIIPVDGLKNQKLFDELRMNYIKELDRIIACKRKNPTSC +SRRFYQLTKVLDSVTPIAKDLHQFTFDLLIKAHMVSVDYPEMMAEIISVQVPKILS +>UNIPROT|Q9VSE9/1-484 estrogen-related receptor +MSDGVSILHIKQEVDTPSASCFSPSSKSTATQSGTNGLKSSPSVSPERQLCSSTTSLSCDLHNVSLSNDGDS +LKGSGTSGGNGGGGGGGTSGGNATNASAGAGSGSVRDELRRLCLVCGDVASGFHYGVASCEACKAFFKRTIQ +GNIEYTCPANNECEINKRRRKACQACRFQKCLLMGMLKEGVRLDRVRGGRQKYRRNPVSNSYQTMQLLYQSN +TTSLCDVKILEVLNSYEPDALSVQTPPPQVHTTSITNDEASSSSGSIKLESSVVTPNGTCIFQNNNNNDPNE +ILSVLSDIYDKELVSVIGWAKQIPGFIDLPLNDQMKLLQVSWAEILTLQLTFRSLPFNGKLCFATDVWMDEH +LAKECGYTEFYYHCVQIAQRMERISPRREEYYLLKALLLANCDILLDDQSSLRAFRDTILNSLNDVVYLLRH +SSAVSHQQQLLLLLPSLRQADDILRRFWRGIARDEVITMKKLFLEMLEPLAR +>UNIPROT|Q90ZM8/1-554 estrogen receptor +ARGFSEAHGYEYSGASLYQPLPPSCTEFSIGAHQQQQHQHQHHQHQHQQHHHQQQQQQPQPQQNGVLGEGQS +SHLSYLPPSTELPQYVPSSPSAPYSMELGAGRPHGYDPGPQSLYRGGVESSAPPYSEQQQVVGGGGAMSAMG +LTEPRHVSSGSLPSSTRPERSTQFCAVCSDYASGYHYGVWSCEGCKAFFKRSTQGHNDYMCPATNQCTIDRN +RRKSCQACRLRKCYEVGMVKGVRKDRKGFRGVKHKRKRPIPQKNGGEGGAGGGQDVSETRPQGERPSGPRDR +ESAVSSLEADQVISALLEAEPPTVLSSYDPDKPVTEASLMAALTSLADRELVHMITWAKKIPGFTAIGLSDQ +VQLLECCWLEILIVGLIWRSIDRPGQLHFAPNLILGREDARNVEGMLDMFDMLLVTVSRFRELHLRREEYVC +LKAMILLNSGVFFCLSNSAGEQTNVQLIQQILEKVMDALGSTIGHIEASPPQHSRRLSQLLLLLSQIRHISN +KGIEHLNSMKRKNVIPLYDLLLELLDAHSLQNTGLRTSPPPQDFRATLVP diff --git a/help/html/features/multipleViews.html b/help/html/features/multipleViews.html index dc9160f..2506456 100644 --- a/help/html/features/multipleViews.html +++ b/help/html/features/multipleViews.html @@ -47,8 +47,8 @@ something more meaningful.

as tabs within a single alignment window. They can be viewed simultanously by pressing X (or via "View→Expand") to expand each view into its own linked alignment window. Expanded views -are gathered back into into a single tabbed alignment window by pressing -G, or by selecting "View→Gather"). +are gathered back into a single tabbed alignment window by pressing +G, or by selecting "View→Gather".

Hidden Sequence Representatives and Multiple Views

diff --git a/lib/jersey-client-1.19.jar b/lib/jersey-client-1.19.jar new file mode 100644 index 0000000..c9e0f56 Binary files /dev/null and b/lib/jersey-client-1.19.jar differ diff --git a/lib/jersey-core-1.19.jar b/lib/jersey-core-1.19.jar new file mode 100644 index 0000000..92feb63 Binary files /dev/null and b/lib/jersey-core-1.19.jar differ diff --git a/lib/jersey-json-1.19.jar b/lib/jersey-json-1.19.jar new file mode 100644 index 0000000..b609411 Binary files /dev/null and b/lib/jersey-json-1.19.jar differ diff --git a/lib/jsr311-api-1.1.1.jar b/lib/jsr311-api-1.1.1.jar new file mode 100644 index 0000000..ec8bc81 Binary files /dev/null and b/lib/jsr311-api-1.1.1.jar differ diff --git a/resources/images/dna.png b/resources/images/dna.png new file mode 100644 index 0000000..f9854fe Binary files /dev/null and b/resources/images/dna.png differ diff --git a/resources/images/error.png b/resources/images/error.png new file mode 100644 index 0000000..6d68a8c Binary files /dev/null and b/resources/images/error.png differ diff --git a/resources/images/good.png b/resources/images/good.png new file mode 100644 index 0000000..ebbacc9 Binary files /dev/null and b/resources/images/good.png differ diff --git a/resources/images/loading.gif b/resources/images/loading.gif new file mode 100644 index 0000000..23ed238 Binary files /dev/null and b/resources/images/loading.gif differ diff --git a/resources/images/protein.png b/resources/images/protein.png new file mode 100644 index 0000000..3789793 Binary files /dev/null and b/resources/images/protein.png differ diff --git a/resources/images/sugar.png b/resources/images/sugar.png new file mode 100644 index 0000000..5d62ce5 Binary files /dev/null and b/resources/images/sugar.png differ diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index 2e37e06..0d3d491 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -216,6 +216,7 @@ label.none = None label.above_identity_threshold = Above Identity Threshold label.show_sequence_features = Show Sequence Features label.nucleotide = Nucleotide +label.protein = Protein label.to_new_alignment = To New Alignment label.to_this_alignment = Add To This Alignment label.apply_colour_to_all_groups = Apply Colour To All Groups @@ -228,14 +229,17 @@ label.documentation = Documentation label.about = About... label.show_sequence_limits = Show Sequence Limits label.feature_settings = Feature Settings... -label.sequence_features = Sequence Features label.all_columns = All Columns label.all_sequences = All Sequences label.selected_columns = Selected Columns label.selected_sequences = Selected Sequences +label.except_selected_sequences = All except selected sequences label.all_but_selected_region = All but Selected Region (Shift+Ctrl+H) label.selected_region = Selected Region label.all_sequences_columns = All Sequences and Columns +label.hide_insertions = Hide columns gapped for selection +label.hide_selected_annotations = Hide selected annotations +label.show_selected_annotations = Show selected annotations label.group_consensus = Group Consensus label.group_conservation = Group Conservation label.show_consensus_histogram = Show Consensus Histogram @@ -382,6 +386,7 @@ label.automatically_associate_pdb_files_with_sequences_same_name = Do you want t label.automatically_associate_pdb_files_by_name = Automatically Associate PDB files by name label.ignore_unmatched_dropped_files_info = Do you want to ignore the {0} files whose names did not match any sequence IDs ? label.ignore_unmatched_dropped_files = Ignore unmatched dropped files? +label.view_name_original = Original label.enter_view_name = Enter View Name label.enter_label = Enter label label.enter_label_for_the_structure = Enter a label for the structure? @@ -480,8 +485,6 @@ label.load_associated_tree = Load Associated Tree ... label.load_features_annotations = Load Features/Annotations ... label.export_features = Export Features ... label.export_annotations = Export Annotations ... -label.jalview_copy = Copy (Jalview Only) -label.jalview_cut = Cut (Jalview Only) label.to_upper_case = To Upper Case label.to_lower_case = To Lower Case label.toggle_case = Toggle Case @@ -576,7 +579,8 @@ label.database_references = Database References label.share_selection_across_views = Share selection across views label.scroll_highlighted_regions = Scroll to highlighted regions label.gap_symbol = Gap Symbol -label.alignment_colour = Alignment Colour +label.prot_alignment_colour = Protein Alignment Colour +label.nuc_alignment_colour = Nucleotide Alignment Colour label.address = Address label.port = Port label.default_browser_unix = Default Browser (Unix) @@ -671,7 +675,7 @@ label.view_structure = View Structure label.clustalx_colours = Clustalx colours label.above_identity_percentage = Above % Identity label.create_sequence_details_report_annotation_for = Annotation for {0} -label.sequece_details_for = Sequece Details for {0} +label.sequence_details_for = Sequence Details for {0} label.sequence_name = Sequence Name label.sequence_description = Sequence Description label.edit_sequence_name_description = Edit Sequence Name/Description @@ -689,12 +693,15 @@ label.save_png_image = Save As PNG Image label.load_tree_for_sequence_set = Load a tree for this sequence set label.export_image = Export Image label.vamsas_store = VAMSAS store -label.translate_cDNA = Translate cDNA +label.translate_cDNA = Translate as cDNA +label.linked_view_title = Linked cDNA and protein view +label.align = Align label.extract_scores = Extract Scores label.get_cross_refs = Get Cross References label.sort_alignment_new_tree = Sort Alignment With New Tree label.add_sequences = Add Sequences label.new_window = New Window +label.split_window = Split Window label.refresh_available_sources = Refresh Available Sources label.use_registry = Use Registry label.add_local_source = Add Local Source @@ -734,6 +741,7 @@ label.paste_new_window = Paste To New Window label.settings_for_param = Settings for {0} label.view_params = View {0} label.select_all_views = Select all views +label.all_views = All Views label.align_sequences_to_existing_alignment = Align sequences to an existing alignment label.realign_with_params = Realign with {0} label.calcname_with_default_settings = {0} with Defaults @@ -775,7 +783,6 @@ label.use_sequence_id_1 = Use $SEQUENCE_ID$ or $SEQUENCE_ID=//=$ label.use_sequence_id_2 = \nto embed sequence id in URL label.ws_parameters_for = Parameters for {0} label.switch_server = Switch server -label.open_jabaws_web_page = Opens the JABAWS server's homepage in web browser label.choose_jabaws_server = Choose a server for running this service label.services_at = Services at {0} label.rest_client_submit = {0} using {1} @@ -1178,6 +1185,13 @@ label.show_logo = Show Logo label.normalise_logo = Normalise Logo label.no_colour_selection_in_scheme = Please, make a colour selection before to apply colour scheme label.no_colour_selection_warn = Error saving colour scheme +label.open_split_window? = Would you like to open as a split window, with cDNA and protein linked? +label.open_split_window = Open split window +label.no_mappings = No mappings found +label.mapping_failed = No sequence mapping could be made between the alignments.
A mapping requires sequence names to match, and equivalent sequence lengths. +action.no = No +action.yes = Yes +label.for = for label.select_by_annotation = Select By Annotation action.select_by_annotation = Select by Annotation... label.threshold_filter = Threshold Filter @@ -1192,3 +1206,22 @@ label.search_filter = Search Filter label.display_name = Display Label label.description = Description label.include_description= Include Description +action.back = Back +label.hide_insertions = Hide Insertions +label.mark_as_representative = Mark as representative +label.open_jabaws_web_page = Open JABAWS web page +label.opens_the_jabaws_server_homepage = Opens the JABAWS server's homepage in web browser +label.pdb_sequence_getcher = PDB Sequence Fetcher +label.result = result +label.results = results +label.structure_chooser = Structure Chooser +label.select = Select : +label.invert = Invert +label.select_pdb_file = Select PDB File +info.select_filter_option = Select Filter Option/Manual Entry +info.associate_wit_sequence = Associate with Sequence +label.search_result = Search Result +label.found_structures_summary = Found Structures Summary +label.configure_displayed_columns = Configure Displayed Columns +label.start_jalview = Start Jalview +label.biojs_html_export = BioJS diff --git a/schemas/jalview.xsd b/schemas/jalview.xsd index f2ba0a5..d643648 100755 --- a/schemas/jalview.xsd +++ b/schemas/jalview.xsd @@ -359,12 +359,11 @@ type="xs:boolean" use="optional" default="true" /> - + - - + @@ -388,6 +387,14 @@ + + + + The viewport id of this viewport's (cdna/protein) coding complement, if any + + + atoms) { if (!seqColoursReady) { return; } - - if (highlightRes != null && highlightRes.contains((atomIndex - 1) + "")) + for (AtomSpec atom : atoms) { - return; + int atomIndex = atom.getAtomIndex(); + + if (highlightRes != null + && highlightRes.contains((atomIndex - 1) + "")) + { + continue; + } + + highlightAtom(atomIndex); } + redrawneeded = true; + repaint(); + } + + /** + * @param atomIndex + */ + protected void highlightAtom(int atomIndex) + { int index = -1; Bond tmpBond; for (index = 0; index < mainchain.bonds.size(); index++) @@ -1178,9 +1218,6 @@ public class AppletPDBCanvas extends Panel implements MouseListener, break; } } - - redrawneeded = true; - repaint(); } public Color getColour(int atomIndex, int pdbResNum, String chain, diff --git a/src/MCview/Atom.java b/src/MCview/Atom.java index b600bc9..9cbcebb 100755 --- a/src/MCview/Atom.java +++ b/src/MCview/Atom.java @@ -20,7 +20,7 @@ */ package MCview; -import java.awt.*; +import java.awt.Color; public class Atom { @@ -77,16 +77,16 @@ public class Atom chain = str.substring(21, 22); resNumber = Integer.parseInt(str.substring(22, 26).trim()); - resNumIns = str.substring(22, 27); + resNumIns = str.substring(22, 27).trim(); insCode = str.substring(26, 27).charAt(0); - this.x = (float) (new Float(str.substring(30, 38).trim()).floatValue()); - this.y = (float) (new Float(str.substring(38, 46).trim()).floatValue()); - this.z = (float) (new Float(str.substring(47, 55).trim()).floatValue()); + this.x = (new Float(str.substring(30, 38).trim()).floatValue()); + this.y = (new Float(str.substring(38, 46).trim()).floatValue()); + this.z = (new Float(str.substring(47, 55).trim()).floatValue()); // optional entries - see JAL-730 String tm = str.substring(54, 60).trim(); if (tm.length() > 0) { - occupancy = (float) (new Float(tm)).floatValue(); + occupancy = (new Float(tm)).floatValue(); } else { @@ -96,7 +96,7 @@ public class Atom tm = str.substring(60, 66).trim(); if (tm.length() > 0) { - tfactor = (float) (new Float(tm).floatValue()); + tfactor = (new Float(tm).floatValue()); } else { diff --git a/src/MCview/PDBCanvas.java b/src/MCview/PDBCanvas.java index f6e6427..6f76a25 100644 --- a/src/MCview/PDBCanvas.java +++ b/src/MCview/PDBCanvas.java @@ -20,18 +20,37 @@ */ package MCview; -import java.io.*; -import java.util.*; - +import jalview.analysis.AlignSeq; +import jalview.datamodel.PDBEntry; +import jalview.datamodel.SequenceI; +import jalview.gui.AlignmentPanel; +import jalview.gui.FeatureRenderer; +import jalview.gui.SequenceRenderer; +import jalview.structure.AtomSpec; +import jalview.structure.StructureListener; +import jalview.structure.StructureMapping; +import jalview.structure.StructureSelectionManager; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; // JBPNote TODO: This class is quite noisy - needs proper log.info/log.debug -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -import jalview.analysis.*; -import jalview.datamodel.*; -import jalview.gui.*; -import jalview.structure.*; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.io.PrintStream; +import java.util.List; +import java.util.Vector; + +import javax.swing.JPanel; +import javax.swing.ToolTipManager; public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListener, StructureListener @@ -134,7 +153,9 @@ public class PDBCanvas extends JPanel implements MouseListener, pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol); if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE)) + { pdbentry.setFile("INLINE" + pdb.id); + } } catch (Exception ex) { @@ -167,17 +188,17 @@ public class PDBCanvas extends JPanel implements MouseListener, { mappingDetails.append("\n\nPDB Sequence is :\nSequence = " - + ((PDBChain) pdb.chains.elementAt(i)).sequence + + pdb.chains.elementAt(i).sequence .getSequenceAsString()); mappingDetails.append("\nNo of residues = " - + ((PDBChain) pdb.chains.elementAt(i)).residues.size() + + pdb.chains.elementAt(i).residues.size() + "\n\n"); // Now lets compare the sequences to get // the start and end points. // Align the sequence to the pdb AlignSeq as = new AlignSeq(sequence, - ((PDBChain) pdb.chains.elementAt(i)).sequence, "pep"); + pdb.chains.elementAt(i).sequence, "pep"); as.calcScoreMatrix(); as.traceAlignment(); PrintStream ps = new PrintStream(System.out) @@ -210,7 +231,7 @@ public class PDBCanvas extends JPanel implements MouseListener, mappingDetails.append("\nSEQ start/end " + seqstart + " " + seqend); } - mainchain = (PDBChain) pdb.chains.elementAt(maxchain); + mainchain = pdb.chains.elementAt(maxchain); mainchain.pdbstart = pdbstart; mainchain.pdbend = pdbend; @@ -254,9 +275,9 @@ public class PDBCanvas extends JPanel implements MouseListener, for (int ii = 0; ii < pdb.chains.size(); ii++) { - if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) + if (pdb.chains.elementAt(ii).isVisible) { - Vector tmp = ((PDBChain) pdb.chains.elementAt(ii)).bonds; + Vector tmp = pdb.chains.elementAt(ii).bonds; for (int i = 0; i < tmp.size(); i++) { @@ -286,9 +307,9 @@ public class PDBCanvas extends JPanel implements MouseListener, for (int ii = 0; ii < pdb.chains.size(); ii++) { - if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) + if (pdb.chains.elementAt(ii).isVisible) { - Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds; + Vector bonds = pdb.chains.elementAt(ii).bonds; for (int i = 0; i < bonds.size(); i++) { @@ -362,9 +383,9 @@ public class PDBCanvas extends JPanel implements MouseListener, * System.out.println("zmax " + max[2] + " min " + min[2]); */ - width[0] = (float) Math.abs(max[0] - min[0]); - width[1] = (float) Math.abs(max[1] - min[1]); - width[2] = (float) Math.abs(max[2] - min[2]); + width[0] = Math.abs(max[0] - min[0]); + width[1] = Math.abs(max[1] - min[1]); + width[2] = Math.abs(max[2] - min[2]); maxwidth = width[0]; @@ -421,9 +442,9 @@ public class PDBCanvas extends JPanel implements MouseListener, // Find centre coordinate for (int ii = 0; ii < pdb.chains.size(); ii++) { - if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) + if (pdb.chains.elementAt(ii).isVisible) { - Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds; + Vector bonds = pdb.chains.elementAt(ii).bonds; bsize += bonds.size(); @@ -537,7 +558,7 @@ public class PDBCanvas extends JPanel implements MouseListener, { for (int ii = 0; ii < pdb.chains.size(); ii++) { - chain = (PDBChain) pdb.chains.elementAt(ii); + chain = pdb.chains.elementAt(ii); for (int i = 0; i < chain.bonds.size(); i++) { @@ -751,7 +772,7 @@ public class PDBCanvas extends JPanel implements MouseListener, repaint(); if (foundchain != -1) { - PDBChain chain = (PDBChain) pdb.chains.elementAt(foundchain); + PDBChain chain = pdb.chains.elementAt(foundchain); if (chain == mainchain) { if (fatom.alignmentMapping != -1) @@ -797,7 +818,7 @@ public class PDBCanvas extends JPanel implements MouseListener, PDBChain chain = null; if (foundchain != -1) { - chain = (PDBChain) pdb.chains.elementAt(foundchain); + chain = pdb.chains.elementAt(foundchain); if (chain == mainchain) { mouseOverStructure(fatom.resNumber, chain.id); @@ -840,18 +861,18 @@ public class PDBCanvas extends JPanel implements MouseListener, if ((evt.getModifiers() & Event.META_MASK) != 0) { - objmat.rotatez((float) ((mx - omx))); + objmat.rotatez(((mx - omx))); } else { - objmat.rotatex((float) ((my - omy))); - objmat.rotatey((float) ((omx - mx))); + objmat.rotatex(((my - omy))); + objmat.rotatey(((omx - mx))); } // Alter the bonds for (int ii = 0; ii < pdb.chains.size(); ii++) { - Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds; + Vector bonds = pdb.chains.elementAt(ii).bonds; for (int i = 0; i < bonds.size(); i++) { @@ -892,11 +913,11 @@ public class PDBCanvas extends JPanel implements MouseListener, for (int ii = 0; ii < pdb.chains.size(); ii++) { - PDBChain chain = (PDBChain) pdb.chains.elementAt(ii); + PDBChain chain = pdb.chains.elementAt(ii); if (chain.isVisible) { - Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds; + Vector bonds = pdb.chains.elementAt(ii).bonds; for (int i = 0; i < bonds.size(); i++) { @@ -948,13 +969,13 @@ public class PDBCanvas extends JPanel implements MouseListener, for (int ii = 0; ii < pdb.chains.size(); ii++) { - PDBChain chain = (PDBChain) pdb.chains.elementAt(ii); + PDBChain chain = pdb.chains.elementAt(ii); int truex; Bond tmpBond = null; if (chain.isVisible) { - Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds; + Vector bonds = pdb.chains.elementAt(ii).bonds; for (int i = 0; i < bonds.size(); i++) { @@ -995,7 +1016,7 @@ public class PDBCanvas extends JPanel implements MouseListener, if (fatom != null) // )&& chain.ds != null) { - chain = (PDBChain) pdb.chains.elementAt(foundchain); + chain = pdb.chains.elementAt(foundchain); } } @@ -1060,7 +1081,7 @@ public class PDBCanvas extends JPanel implements MouseListener, { for (int ii = 0; ii < pdb.chains.size(); ii++) { - PDBChain chain = (PDBChain) pdb.chains.elementAt(ii); + PDBChain chain = pdb.chains.elementAt(ii); chain.isVisible = b; } mainchain.isVisible = true; @@ -1081,7 +1102,9 @@ public class PDBCanvas extends JPanel implements MouseListener, public void mouseOverStructure(int pdbResNum, String chain) { if (lastMessage == null || !lastMessage.equals(pdbResNum + chain)) + { ssm.mouseOverStructure(pdbResNum, chain, pdbentry.getFile()); + } lastMessage = pdbResNum + chain; } @@ -1090,19 +1113,42 @@ public class PDBCanvas extends JPanel implements MouseListener, StringBuffer eval = new StringBuffer(); - public void highlightAtom(int atomIndex, int pdbResNum, String chain, - String pdbfile) + /** + * Highlight the specified atoms in the structure. + * + * @param atoms + */ + @Override + public void highlightAtoms(List atoms) { if (!seqColoursReady) { return; } - if (highlightRes != null && highlightRes.contains((atomIndex - 1) + "")) + for (AtomSpec atom : atoms) { - return; + int atomIndex = atom.getAtomIndex(); + if (highlightRes != null + && highlightRes.contains((atomIndex - 1) + "")) + { + continue; + } + + highlightAtom(atomIndex); } + redrawneeded = true; + repaint(); + } + + /** + * Highlight the atom at the specified index. + * + * @param atomIndex + */ + protected void highlightAtom(int atomIndex) + { int index = -1; Bond tmpBond; for (index = 0; index < mainchain.bonds.size(); index++) @@ -1138,9 +1184,6 @@ public class PDBCanvas extends JPanel implements MouseListener, break; } } - - redrawneeded = true; - repaint(); } public Color getColour(int atomIndex, int pdbResNum, String chain, diff --git a/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java b/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java index 2c40e1c..b74e65a 100644 --- a/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java +++ b/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java @@ -783,8 +783,8 @@ public class ChimeraManager List reply = new ArrayList(); BufferedReader response = null; try { - response = HttpClientUtils.doHttpUrlPost(restUrl, - commands); + response = HttpClientUtils + .doHttpUrlPost(restUrl, commands, 100, 2000); String line = ""; while ((line = response.readLine()) != null) { reply.add(line); diff --git a/src/ext/vamsas/ServiceHandle.java b/src/ext/vamsas/ServiceHandle.java index 442e5f7..83412ea 100755 --- a/src/ext/vamsas/ServiceHandle.java +++ b/src/ext/vamsas/ServiceHandle.java @@ -128,15 +128,15 @@ public class ServiceHandle implements java.io.Serializable public synchronized boolean equals(java.lang.Object obj) { - if (!(obj instanceof ServiceHandle)) + if (obj == null) { return false; } - ServiceHandle other = (ServiceHandle) obj; - if (obj == null) + if (!(obj instanceof ServiceHandle)) { return false; } + ServiceHandle other = (ServiceHandle) obj; if (this == obj) { return true; diff --git a/src/ext/vamsas/ServiceHandles.java b/src/ext/vamsas/ServiceHandles.java index 45c49d8..5ed466f 100755 --- a/src/ext/vamsas/ServiceHandles.java +++ b/src/ext/vamsas/ServiceHandles.java @@ -57,15 +57,15 @@ public class ServiceHandles implements java.io.Serializable public synchronized boolean equals(java.lang.Object obj) { - if (!(obj instanceof ServiceHandles)) + if (obj == null) { return false; } - ServiceHandles other = (ServiceHandles) obj; - if (obj == null) + if (!(obj instanceof ServiceHandles)) { return false; } + ServiceHandles other = (ServiceHandles) obj; if (this == obj) { return true; diff --git a/src/jalview/analysis/AAFrequency.java b/src/jalview/analysis/AAFrequency.java index b96bf8e..d6088e4 100755 --- a/src/jalview/analysis/AAFrequency.java +++ b/src/jalview/analysis/AAFrequency.java @@ -20,10 +20,19 @@ */ package jalview.analysis; -import java.util.*; - +import jalview.datamodel.AlignedCodonFrame; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.Annotation; +import jalview.datamodel.SequenceI; import jalview.util.Format; -import jalview.datamodel.*; +import jalview.util.MappingUtils; +import jalview.util.QuickSort; + +import java.util.Arrays; +import java.util.Hashtable; +import java.util.List; +import java.util.Set; /** * Takes in a vector or array of sequences and column start and column end and @@ -36,8 +45,8 @@ import jalview.datamodel.*; */ public class AAFrequency { - // No need to store 1000s of strings which are not - // visible to the user. + private static final int TO_UPPER_CASE = 'A' - 'a'; // -32 + public static final String MAXCOUNT = "C"; public static final String MAXRESIDUE = "R"; @@ -48,6 +57,21 @@ public class AAFrequency public static final String PROFILE = "P"; + public static final String ENCODED_CHARS = "E"; + + /* + * Quick look-up of String value of char 'A' to 'Z' + */ + private static final String[] CHARS = new String['Z' - 'A' + 1]; + + static + { + for (char c = 'A'; c <= 'Z'; c++) + { + CHARS[c - 'A'] = String.valueOf(c); + } + } + public static final Hashtable[] calculate(List list, int start, int end) { @@ -83,16 +107,11 @@ public class AAFrequency } public static final void calculate(SequenceI[] sequences, int start, - int end, Hashtable[] result) - { - calculate(sequences, start, end, result, false); - } - - public static final void calculate(SequenceI[] sequences, int start, int end, Hashtable[] result, boolean profile) { Hashtable residueHash; - int maxCount, nongap, i, j, v, jSize = sequences.length; + int maxCount, nongap, i, j, v; + int jSize = sequences.length; String maxResidue; char c = '-'; float percentage; @@ -134,7 +153,7 @@ public class AAFrequency } else if ('a' <= c && c <= 'z') { - c -= 32; // ('a' - 'A'); + c += TO_UPPER_CASE; } nongap++; @@ -153,20 +172,21 @@ public class AAFrequency } else { - for (v = 'A'; v < 'Z'; v++) + for (v = 'A'; v <= 'Z'; v++) { - if (values[v] < 2 || values[v] < maxCount) + // TODO why ignore values[v] == 1? + if (values[v] < 1 /* 2 */|| values[v] < maxCount) { continue; } if (values[v] > maxCount) { - maxResidue = String.valueOf((char) v); + maxResidue = CHARS[v - 'A']; } else if (values[v] == maxCount) { - maxResidue += String.valueOf((char) v); + maxResidue += CHARS[v - 'A']; } maxCount = values[v]; } @@ -177,6 +197,7 @@ public class AAFrequency } if (profile) { + // TODO use a 1-dimensional array with jSize, nongap in [0] and [1] residueHash.put(PROFILE, new int[][] { values, new int[] { jSize, nongap } }); @@ -218,17 +239,37 @@ public class AAFrequency { completeConsensus(consensus, hconsensus, iStart, width, ignoreGapsInConsensusCalculation, includeAllConsSymbols, null, - nseq); // new - // char[] - // { 'A', 'C', 'G', 'T', 'U' }); + nseq); } + /** + * Derive the consensus annotations to be added to the alignment for display. + * This does not recompute the raw data, but may be called on a change in + * display options, such as 'show logo', which may in turn result in a change + * in the derived values. + * + * @param consensus + * the annotation row to add annotations to + * @param hconsensus + * the source consensus data + * @param iStart + * start column + * @param width + * end column + * @param ignoreGapsInConsensusCalculation + * if true, use the consensus calculated ignoring gaps + * @param includeAllConsSymbols + * if true include all consensus symbols, else just show modal + * residue + * @param alphabet + * @param nseq + * number of sequences + */ public static void completeConsensus(AlignmentAnnotation consensus, Hashtable[] hconsensus, int iStart, int width, boolean ignoreGapsInConsensusCalculation, boolean includeAllConsSymbols, char[] alphabet, long nseq) { - float tval, value; if (consensus == null || consensus.annotations == null || consensus.annotations.length < width) { @@ -236,26 +277,9 @@ public class AAFrequency // initialised properly return; } - String fmtstr = "%3.1f"; - int precision = 0; - while (nseq >= 10) - { - precision++; - nseq /= 10; - } - final Format fmt; - if (precision > 1) - { - // if (precision>2) - { - fmtstr = "%" + (2 + precision) + "." + (precision) + "f"; - } - fmt = new Format(fmtstr); - } - else - { - fmt = null; - } + + final Format fmt = getPercentageFormat(nseq); + for (int i = iStart; i < width; i++) { Hashtable hci; @@ -266,119 +290,377 @@ public class AAFrequency consensus.annotations[i] = null; continue; } - value = 0; - Float fv; - if (ignoreGapsInConsensusCalculation) - { - fv = (Float) hci.get(AAFrequency.PID_NOGAPS); - } - else - { - fv = (Float) hci.get(AAFrequency.PID_GAPS); - } + Float fv = (Float) hci + .get(ignoreGapsInConsensusCalculation ? PID_NOGAPS : PID_GAPS); if (fv == null) { consensus.annotations[i] = null; // data has changed below us .. give up and continue; } - value = fv.floatValue(); + float value = fv.floatValue(); String maxRes = hci.get(AAFrequency.MAXRESIDUE).toString(); - String mouseOver = hci.get(AAFrequency.MAXRESIDUE) + " "; + StringBuilder mouseOver = new StringBuilder(64); if (maxRes.length() > 1) { - mouseOver = "[" + maxRes + "] "; + mouseOver.append("[").append(maxRes).append("] "); maxRes = "+"; } + else + { + mouseOver.append(hci.get(AAFrequency.MAXRESIDUE) + " "); + } int[][] profile = (int[][]) hci.get(AAFrequency.PROFILE); + int sequenceCount = profile[1][0]; + int nonGappedCount = profile[1][1]; + int normalisedBy = ignoreGapsInConsensusCalculation ? nonGappedCount + : sequenceCount; if (profile != null && includeAllConsSymbols) { - mouseOver = ""; + mouseOver.setLength(0); if (alphabet != null) { for (int c = 0; c < alphabet.length; c++) { - tval = profile[0][alphabet[c]] * 100f - / profile[1][ignoreGapsInConsensusCalculation ? 1 : 0]; - mouseOver += ((c == 0) ? "" : "; ") + alphabet[c] + " " - + ((fmt != null) ? fmt.form(tval) : ((int) tval)) + "%"; + float tval = profile[0][alphabet[c]] * 100f / normalisedBy; + mouseOver + .append(((c == 0) ? "" : "; ")) + .append(alphabet[c]) + .append(" ") + .append(((fmt != null) ? fmt.form(tval) : ((int) tval))) + .append("%"); } } else { - Object[] ca = new Object[profile[0].length]; + // TODO do this sort once only in calculate()? + // char[][] ca = new char[profile[0].length][]; + char[] ca = new char[profile[0].length]; float[] vl = new float[profile[0].length]; for (int c = 0; c < ca.length; c++) { - ca[c] = new char[] - { (char) c }; + ca[c] = (char) c; + // ca[c] = new char[] + // { (char) c }; vl[c] = profile[0][c]; } - ; - jalview.util.QuickSort.sort(vl, ca); - for (int p = 0, c = ca.length - 1; profile[0][((char[]) ca[c])[0]] > 0; c--) + QuickSort.sort(vl, ca); + for (int p = 0, c = ca.length - 1; profile[0][ca[c]] > 0; c--) { - if (((char[]) ca[c])[0] != '-') + final char residue = ca[c]; + if (residue != '-') { - tval = profile[0][((char[]) ca[c])[0]] - * 100f - / profile[1][ignoreGapsInConsensusCalculation ? 1 : 0]; - mouseOver += ((p == 0) ? "" : "; ") + ((char[]) ca[c])[0] - + " " - + ((fmt != null) ? fmt.form(tval) : ((int) tval)) - + "%"; + float tval = profile[0][residue] * 100f / normalisedBy; + mouseOver + .append((((p == 0) ? "" : "; "))) + .append(residue) + .append(" ") + .append(((fmt != null) ? fmt.form(tval) + : ((int) tval))).append("%"); p++; - } } - } } else { - mouseOver += ((fmt != null) ? fmt.form(value) : ((int) value)) - + "%"; + mouseOver.append( + (((fmt != null) ? fmt.form(value) : ((int) value)))) + .append("%"); } - consensus.annotations[i] = new Annotation(maxRes, mouseOver, ' ', + consensus.annotations[i] = new Annotation(maxRes, + mouseOver.toString(), ' ', value); } } /** - * get the sorted profile for the given position of the consensus + * Returns a Format designed to show all significant figures for profile + * percentages. For less than 100 sequences, returns null (the integer + * percentage value will be displayed). For 100-999 sequences, returns "%3.1f" + * + * @param nseq + * @return + */ + protected static Format getPercentageFormat(long nseq) + { + int scale = 0; + while (nseq >= 10) + { + scale++; + nseq /= 10; + } + return scale <= 1 ? null : new Format("%3." + (scale - 1) + "f"); + } + + /** + * Returns the sorted profile for the given consensus data. The returned array + * contains + * + *
+   *    [profileType, numberOfValues, nonGapCount, charValue1, percentage1, charValue2, percentage2, ...]
+   * in descending order of percentage value
+   * 
* * @param hconsensus + * the data table from which to extract and sort values + * @param ignoreGaps + * if true, only non-gapped values are included in percentage + * calculations * @return */ public static int[] extractProfile(Hashtable hconsensus, - boolean ignoreGapsInConsensusCalculation) + boolean ignoreGaps) { int[] rtnval = new int[64]; int[][] profile = (int[][]) hconsensus.get(AAFrequency.PROFILE); if (profile == null) + { return null; - Object[] ca = new Object[profile[0].length]; + } + char[] ca = new char[profile[0].length]; float[] vl = new float[profile[0].length]; for (int c = 0; c < ca.length; c++) { - ca[c] = new char[] - { (char) c }; + ca[c] = (char) c; vl[c] = profile[0][c]; } - ; - jalview.util.QuickSort.sort(vl, ca); - rtnval[0] = 2; - rtnval[1] = 0; - for (int c = ca.length - 1; profile[0][((char[]) ca[c])[0]] > 0; c--) + QuickSort.sort(vl, ca); + int nextArrayPos = 2; + int totalPercentage = 0; + int distinctValuesCount = 0; + final int divisor = profile[1][ignoreGaps ? 1 : 0]; + for (int c = ca.length - 1; profile[0][ca[c]] > 0; c--) + { + if (ca[c] != '-') + { + rtnval[nextArrayPos++] = ca[c]; + final int percentage = (int) (profile[0][ca[c]] * 100f / divisor); + rtnval[nextArrayPos++] = percentage; + totalPercentage += percentage; + distinctValuesCount++; + } + } + rtnval[0] = distinctValuesCount; + rtnval[1] = totalPercentage; + int[] result = new int[rtnval.length + 1]; + result[0] = AlignmentAnnotation.SEQUENCE_PROFILE; + System.arraycopy(rtnval, 0, result, 1, rtnval.length); + + return result; + } + + /** + * Extract a sorted extract of cDNA codon profile data. The returned array + * contains + * + *
+   *    [profileType, numberOfValues, totalCount, charValue1, percentage1, charValue2, percentage2, ...]
+   * in descending order of percentage value, where the character values encode codon triplets
+   * 
+ * + * @param hashtable + * @return + */ + public static int[] extractCdnaProfile(Hashtable hashtable, boolean ignoreGaps) + { + // this holds #seqs, #ungapped, and then codon count, indexed by encoded + // codon triplet + int[] codonCounts = (int[]) hashtable.get(PROFILE); + int[] sortedCounts = new int[codonCounts.length - 2]; + System.arraycopy(codonCounts, 2, sortedCounts, 0, + codonCounts.length - 2); + + int[] result = new int[3 + 2 * sortedCounts.length]; + // first value is just the type of profile data + result[0] = AlignmentAnnotation.CDNA_PROFILE; + + char[] codons = new char[sortedCounts.length]; + for (int i = 0; i < codons.length; i++) + { + codons[i] = (char) i; + } + QuickSort.sort(sortedCounts, codons); + int totalPercentage = 0; + int distinctValuesCount = 0; + int j = 3; + int divisor = ignoreGaps ? codonCounts[1] : codonCounts[0]; + for (int i = codons.length - 1; i >= 0; i--) + { + final int codonCount = sortedCounts[i]; + if (codonCount == 0) + { + break; // nothing else of interest here + } + distinctValuesCount++; + result[j++] = codons[i]; + final int percentage = codonCount * 100 / divisor; + result[j++] = percentage; + totalPercentage += percentage; + } + result[2] = totalPercentage; + + /* + * Just return the non-zero values + */ + // todo next value is redundant if we limit the array to non-zero counts + result[1] = distinctValuesCount; + return Arrays.copyOfRange(result, 0, j); + } + + /** + * Compute a consensus for the cDNA coding for a protein alignment. + * + * @param alignment + * the protein alignment (which should hold mappings to cDNA + * sequences) + * @param hconsensus + * the consensus data stores to be populated (one per column) + */ + public static void calculateCdna(AlignmentI alignment, + Hashtable[] hconsensus) + { + final char gapCharacter = alignment.getGapCharacter(); + Set mappings = alignment.getCodonFrames(); + if (mappings == null || mappings.isEmpty()) + { + return; + } + + int cols = alignment.getWidth(); + for (int col = 0; col < cols; col++) + { + // todo would prefer a Java bean for consensus data + Hashtable columnHash = new Hashtable(); + // #seqs, #ungapped seqs, counts indexed by (codon encoded + 1) + int[] codonCounts = new int[66]; + codonCounts[0] = alignment.getSequences().size(); + int ungappedCount = 0; + for (SequenceI seq : alignment.getSequences()) + { + if (seq.getCharAt(col) == gapCharacter) + { + continue; + } + char[] codon = MappingUtils.findCodonFor(seq, col, mappings); + int codonEncoded = CodingUtils.encodeCodon(codon); + if (codonEncoded >= 0) + { + codonCounts[codonEncoded + 2]++; + ungappedCount++; + } + } + codonCounts[1] = ungappedCount; + // todo: sort values here, save counts and codons? + columnHash.put(PROFILE, codonCounts); + hconsensus[col] = columnHash; + } + } + + /** + * Derive displayable cDNA consensus annotation from computed consensus data. + * + * @param consensusAnnotation + * the annotation row to be populated for display + * @param consensusData + * the computed consensus data + * @param showProfileLogo + * if true show all symbols present at each position, else only the + * modal value + * @param nseqs + * the number of sequences in the alignment + */ + public static void completeCdnaConsensus( + AlignmentAnnotation consensusAnnotation, + Hashtable[] consensusData, boolean showProfileLogo, int nseqs) + { + if (consensusAnnotation == null + || consensusAnnotation.annotations == null + || consensusAnnotation.annotations.length < consensusData.length) + { + // called with a bad alignment annotation row - wait for it to be + // initialised properly + return; + } + + // ensure codon triplet scales with font size + consensusAnnotation.scaleColLabel = true; + for (int col = 0; col < consensusData.length; col++) { - if (((char[]) ca[c])[0] != '-') + Hashtable hci = consensusData[col]; + if (hci == null) { - rtnval[rtnval[0]++] = ((char[]) ca[c])[0]; - rtnval[rtnval[0]] = (int) (profile[0][((char[]) ca[c])[0]] * 100f / profile[1][ignoreGapsInConsensusCalculation ? 1 - : 0]); - rtnval[1] += rtnval[rtnval[0]++]; + // gapped protein column? + continue; } + // array holds #seqs, #ungapped, then codon counts indexed by codon + final int[] codonCounts = (int[]) hci.get(PROFILE); + int totalCount = 0; + StringBuilder mouseOver = new StringBuilder(32); + + /* + * First pass - get total count and find the highest + */ + final char[] codons = new char[codonCounts.length - 2]; + for (int j = 2; j < codonCounts.length; j++) + { + final int codonCount = codonCounts[j]; + codons[j - 2] = (char) (j - 2); + totalCount += codonCount; + } + + /* + * Sort array of encoded codons by count ascending - so the modal value + * goes to the end; start by copying the count (dropping the first value) + */ + int[] sortedCodonCounts = new int[codonCounts.length - 2]; + System.arraycopy(codonCounts, 2, sortedCodonCounts, 0, + codonCounts.length - 2); + QuickSort.sort(sortedCodonCounts, codons); + + int modalCodonEncoded = codons[codons.length - 1]; + int modalCodonCount = sortedCodonCounts[codons.length - 1]; + String modalCodon = String.valueOf(CodingUtils + .decodeCodon(modalCodonEncoded)); + if (sortedCodonCounts.length > 1 + && sortedCodonCounts[codons.length - 2] == modalCodonEncoded) + { + modalCodon = "+"; + } + float pid = sortedCodonCounts[sortedCodonCounts.length - 1] * 100 + / (float) totalCount; + + /* + * todo ? Replace consensus hashtable with sorted arrays of codons and + * counts (non-zero only). Include total count in count array [0]. + */ + + /* + * Scan sorted array backwards for most frequent values first. + */ + for (int j = codons.length - 1; j >= 0; j--) + { + int codonCount = sortedCodonCounts[j]; + if (codonCount == 0) + { + break; + } + int codonEncoded = codons[j]; + final int pct = codonCount * 100 / totalCount; + String codon = String + .valueOf(CodingUtils.decodeCodon(codonEncoded)); + Format fmt = getPercentageFormat(nseqs); + String formatted = fmt == null ? Integer.toString(pct) : fmt + .form(pct); + if (showProfileLogo || codonCount == modalCodonCount) + { + mouseOver.append(codon).append(": ").append(formatted) + .append("% "); + } + } + + consensusAnnotation.annotations[col] = new Annotation(modalCodon, + mouseOver.toString(), ' ', pid); } - return rtnval; } } diff --git a/src/jalview/analysis/AlignSeq.java b/src/jalview/analysis/AlignSeq.java index 96c9b72..bd4cc22 100755 --- a/src/jalview/analysis/AlignSeq.java +++ b/src/jalview/analysis/AlignSeq.java @@ -804,19 +804,23 @@ public class AlignSeq } /** - * DOCUMENT ME! + * Returns the given sequence with all of the given gap characters removed. * - * @param gapChar - * DOCUMENT ME! + * @param gapChars + * a string of characters to be treated as gaps * @param seq - * DOCUMENT ME! + * the input sequence * - * @return DOCUMENT ME! + * @return */ - public static String extractGaps(String gapChar, String seq) + public static String extractGaps(String gapChars, String seq) { - StringTokenizer str = new StringTokenizer(seq, gapChar); - StringBuffer newString = new StringBuffer(); + if (gapChars == null || seq == null) + { + return null; + } + StringTokenizer str = new StringTokenizer(seq, gapChars); + StringBuilder newString = new StringBuilder(seq.length()); while (str.hasMoreTokens()) { diff --git a/src/jalview/analysis/AlignmentSorter.java b/src/jalview/analysis/AlignmentSorter.java index d1962c5..2fad332 100755 --- a/src/jalview/analysis/AlignmentSorter.java +++ b/src/jalview/analysis/AlignmentSorter.java @@ -20,10 +20,19 @@ */ package jalview.analysis; -import java.util.*; - -import jalview.datamodel.*; -import jalview.util.*; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.AlignmentOrder; +import jalview.datamodel.SequenceFeature; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; +import jalview.datamodel.SequenceNode; +import jalview.util.Comparison; +import jalview.util.MessageManager; +import jalview.util.QuickSort; + +import java.util.ArrayList; +import java.util.List; /** * Routines for manipulating the order of a multiple sequence alignment TODO: @@ -120,7 +129,7 @@ public class AlignmentSorter seqs[i] = align.getSequenceAt(i); } - QuickSort.sort(scores, 0, scores.length - 1, seqs); + QuickSort.sort(scores, seqs); setReverseOrder(align, seqs); } @@ -169,7 +178,7 @@ public class AlignmentSorter * @param tmp * sequences as a vector */ - private static void setOrder(AlignmentI align, Vector tmp) + private static void setOrder(AlignmentI align, List tmp) { setOrder(align, vectorSubsetToArray(tmp, align.getSequences())); } @@ -285,7 +294,7 @@ public class AlignmentSorter { // MAINTAINS ORIGNAL SEQUENCE ORDER, // ORDERS BY GROUP SIZE - Vector groups = new Vector(); + List groups = new ArrayList(); if (groups.hashCode() != lastGroupHash) { @@ -303,11 +312,11 @@ public class AlignmentSorter { for (int j = 0; j < groups.size(); j++) { - SequenceGroup sg2 = (SequenceGroup) groups.elementAt(j); + SequenceGroup sg2 = groups.get(j); if (sg.getSize() > sg2.getSize()) { - groups.insertElementAt(sg, j); + groups.add(j, sg); break; } @@ -315,22 +324,22 @@ public class AlignmentSorter if (!groups.contains(sg)) { - groups.addElement(sg); + groups.add(sg); } } // NOW ADD SEQUENCES MAINTAINING ALIGNMENT ORDER // ///////////////////////////////////////////// - Vector seqs = new Vector(); + List seqs = new ArrayList(); for (int i = 0; i < groups.size(); i++) { - SequenceGroup sg = (SequenceGroup) groups.elementAt(i); + SequenceGroup sg = groups.get(i); SequenceI[] orderedseqs = sg.getSequencesInOrder(align); for (int j = 0; j < orderedseqs.length; j++) { - seqs.addElement(orderedseqs[j]); + seqs.add(orderedseqs[j]); } } @@ -346,28 +355,8 @@ public class AlignmentSorter } /** - * Converts Vector to array. java 1.18 does not have Vector.toArray() - * - * @param tmp - * Vector of SequenceI objects - * - * @return array of Sequence[] - */ - private static SequenceI[] vectorToArray(Vector tmp) - { - SequenceI[] seqs = new SequenceI[tmp.size()]; - - for (int i = 0; i < tmp.size(); i++) - { - seqs[i] = (SequenceI) tmp.elementAt(i); - } - - return seqs; - } - - /** * Select sequences in order from tmp that is present in mask, and any - * remaining seqeunces in mask not in tmp + * remaining sequences in mask not in tmp * * @param tmp * thread safe collection of sequences @@ -379,6 +368,10 @@ public class AlignmentSorter private static SequenceI[] vectorSubsetToArray(List tmp, List mask) { + // or? + // tmp2 = tmp.retainAll(mask); + // return tmp2.addAll(mask.removeAll(tmp2)) + ArrayList seqs = new ArrayList(); int i, idx; boolean[] tmask = new boolean[mask.size()]; @@ -421,7 +414,7 @@ public class AlignmentSorter public static void sortBy(AlignmentI align, AlignmentOrder order) { // Get an ordered vector of sequences which may also be present in align - Vector tmp = order.getOrder(); + List tmp = order.getOrder(); if (lastOrder == order) { @@ -452,11 +445,12 @@ public class AlignmentSorter * * @return DOCUMENT ME! */ - private static Vector getOrderByTree(AlignmentI align, NJTree tree) + private static List getOrderByTree(AlignmentI align, + NJTree tree) { int nSeq = align.getHeight(); - Vector tmp = new Vector(); + List tmp = new ArrayList(); tmp = _sortByTree(tree.getTopNode(), tmp, align.getSequences()); @@ -494,7 +488,7 @@ public class AlignmentSorter */ public static void sortByTree(AlignmentI align, NJTree tree) { - Vector tmp = getOrderByTree(align, tree); + List tmp = getOrderByTree(align, tree); // tmp should properly permute align with tree. if (lastTree != tree) @@ -522,22 +516,22 @@ public class AlignmentSorter * * @param align * DOCUMENT ME! - * @param seqs + * @param tmp * DOCUMENT ME! */ - private static void addStrays(AlignmentI align, Vector seqs) + private static void addStrays(AlignmentI align, List tmp) { int nSeq = align.getHeight(); for (int i = 0; i < nSeq; i++) { - if (!seqs.contains(align.getSequenceAt(i))) + if (!tmp.contains(align.getSequenceAt(i))) { - seqs.addElement(align.getSequenceAt(i)); + tmp.add(align.getSequenceAt(i)); } } - if (nSeq != seqs.size()) + if (nSeq != tmp.size()) { System.err .println("ERROR: Size still not right even after addStrays"); @@ -556,7 +550,8 @@ public class AlignmentSorter * * @return DOCUMENT ME! */ - private static Vector _sortByTree(SequenceNode node, Vector tmp, + private static List _sortByTree(SequenceNode node, + List tmp, List seqset) { if (node == null) @@ -577,7 +572,7 @@ public class AlignmentSorter // seqset.size()==0 || // seqset.contains(tmp))) { - tmp.addElement(node.element()); + tmp.add((SequenceI) node.element()); } } } @@ -785,10 +780,6 @@ public class AlignmentSorter for (int i = 0; i < seqs.length; i++) { SequenceFeature[] sf = seqs[i].getSequenceFeatures(); - if (sf == null && seqs[i].getDatasetSequence() != null) - { - sf = seqs[i].getDatasetSequence().getSequenceFeatures(); - } if (sf == null) { sf = new SequenceFeature[0]; diff --git a/src/jalview/analysis/AlignmentUtils.java b/src/jalview/analysis/AlignmentUtils.java index b55d58d..6f0125d 100644 --- a/src/jalview/analysis/AlignmentUtils.java +++ b/src/jalview/analysis/AlignmentUtils.java @@ -20,12 +20,30 @@ */ package jalview.analysis; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; + +import jalview.datamodel.AlignedCodon; +import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; +import jalview.datamodel.Mapping; +import jalview.datamodel.SearchResults; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; - -import java.util.ArrayList; -import java.util.List; +import jalview.schemes.ResidueProperties; +import jalview.util.MapList; /** * grab bag of useful alignment manipulation operations Expect these to be @@ -159,4 +177,1039 @@ public class AlignmentUtils } return result; } + + /** + * Returns a map of lists of sequences in the alignment, keyed by sequence + * name. For use in mapping between different alignment views of the same + * sequences. + * + * @see jalview.datamodel.AlignmentI#getSequencesByName() + */ + public static Map> getSequencesByName( + AlignmentI al) + { + Map> theMap = new LinkedHashMap>(); + for (SequenceI seq : al.getSequences()) + { + String name = seq.getName(); + if (name != null) + { + List seqs = theMap.get(name); + if (seqs == null) + { + seqs = new ArrayList(); + theMap.put(name, seqs); + } + seqs.add(seq); + } + } + return theMap; + } + + /** + * Build mapping of protein to cDNA alignment. Mappings are made between + * sequences where the cDNA translates to the protein sequence. Any new + * mappings are added to the protein alignment. Returns true if any mappings + * either already exist or were added, else false. + * + * @param proteinAlignment + * @param cdnaAlignment + * @return + */ + public static boolean mapProteinToCdna( + final AlignmentI proteinAlignment, + final AlignmentI cdnaAlignment) + { + if (proteinAlignment == null || cdnaAlignment == null) + { + return false; + } + + Set mappedDna = new HashSet(); + Set mappedProtein = new HashSet(); + + /* + * First pass - map sequences where cross-references exist. This include + * 1-to-many mappings to support, for example, variant cDNA. + */ + boolean mappingPerformed = mapProteinToCdna(proteinAlignment, + cdnaAlignment, mappedDna, mappedProtein, true); + + /* + * Second pass - map sequences where no cross-references exist. This only + * does 1-to-1 mappings and assumes corresponding sequences are in the same + * order in the alignments. + */ + mappingPerformed |= mapProteinToCdna(proteinAlignment, cdnaAlignment, + mappedDna, mappedProtein, false); + return mappingPerformed; + } + + /** + * Make mappings between compatible sequences (where the cDNA translation + * matches the protein). + * + * @param proteinAlignment + * @param cdnaAlignment + * @param mappedDna + * a set of mapped DNA sequences (to add to) + * @param mappedProtein + * a set of mapped Protein sequences (to add to) + * @param xrefsOnly + * if true, only map sequences where xrefs exist + * @return + */ + protected static boolean mapProteinToCdna( + final AlignmentI proteinAlignment, + final AlignmentI cdnaAlignment, Set mappedDna, + Set mappedProtein, boolean xrefsOnly) + { + boolean mappingPerformed = false; + List thisSeqs = proteinAlignment.getSequences(); + for (SequenceI aaSeq : thisSeqs) + { + boolean proteinMapped = false; + AlignedCodonFrame acf = new AlignedCodonFrame(); + + for (SequenceI cdnaSeq : cdnaAlignment.getSequences()) + { + /* + * Always try to map if sequences have xref to each other; this supports + * variant cDNA or alternative splicing for a protein sequence. + * + * If no xrefs, try to map progressively, assuming that alignments have + * mappable sequences in corresponding order. These are not + * many-to-many, as that would risk mixing species with similar cDNA + * sequences. + */ + if (xrefsOnly && !CrossRef.haveCrossRef(aaSeq, cdnaSeq)) + { + continue; + } + + /* + * Don't map non-xrefd sequences more than once each. This heuristic + * allows us to pair up similar sequences in ordered alignments. + */ + if (!xrefsOnly + && (mappedProtein.contains(aaSeq) || mappedDna + .contains(cdnaSeq))) + { + continue; + } + if (!mappingExists(proteinAlignment.getCodonFrames(), + aaSeq.getDatasetSequence(), cdnaSeq.getDatasetSequence())) + { + MapList map = mapProteinToCdna(aaSeq, cdnaSeq); + if (map != null) + { + acf.addMap(cdnaSeq, aaSeq, map); + mappingPerformed = true; + proteinMapped = true; + mappedDna.add(cdnaSeq); + mappedProtein.add(aaSeq); + } + } + } + if (proteinMapped) + { + proteinAlignment.addCodonFrame(acf); + } + } + return mappingPerformed; + } + + /** + * Answers true if the mappings include one between the given (dataset) + * sequences. + */ + public static boolean mappingExists(Set set, + SequenceI aaSeq, SequenceI cdnaSeq) + { + if (set != null) + { + for (AlignedCodonFrame acf : set) + { + if (cdnaSeq == acf.getDnaForAaSeq(aaSeq)) + { + return true; + } + } + } + return false; + } + + /** + * Build a mapping (if possible) of a protein to a cDNA sequence. The cDNA + * must be three times the length of the protein, possibly after ignoring + * start and/or stop codons, and must translate to the protein. Returns null + * if no mapping is determined. + * + * @param proteinSeqs + * @param cdnaSeq + * @return + */ + public static MapList mapProteinToCdna(SequenceI proteinSeq, + SequenceI cdnaSeq) + { + /* + * Here we handle either dataset sequence set (desktop) or absent (applet). + * Use only the char[] form of the sequence to avoid creating possibly large + * String objects. + */ + final SequenceI proteinDataset = proteinSeq.getDatasetSequence(); + char[] aaSeqChars = proteinDataset != null ? proteinDataset + .getSequence() : proteinSeq.getSequence(); + final SequenceI cdnaDataset = cdnaSeq.getDatasetSequence(); + char[] cdnaSeqChars = cdnaDataset != null ? cdnaDataset.getSequence() + : cdnaSeq.getSequence(); + if (aaSeqChars == null || cdnaSeqChars == null) + { + return null; + } + + /* + * cdnaStart/End, proteinStartEnd are base 1 (for dataset sequence mapping) + */ + final int mappedLength = 3 * aaSeqChars.length; + int cdnaLength = cdnaSeqChars.length; + int cdnaStart = 1; + int cdnaEnd = cdnaLength; + final int proteinStart = 1; + final int proteinEnd = aaSeqChars.length; + + /* + * If lengths don't match, try ignoring stop codon. + */ + if (cdnaLength != mappedLength && cdnaLength > 2) + { + String lastCodon = String.valueOf(cdnaSeqChars, cdnaLength - 3, 3) + .toUpperCase(); + for (String stop : ResidueProperties.STOP) + { + if (lastCodon.equals(stop)) + { + cdnaEnd -= 3; + cdnaLength -= 3; + break; + } + } + } + + /* + * If lengths still don't match, try ignoring start codon. + */ + if (cdnaLength != mappedLength + && cdnaLength > 2 + && String.valueOf(cdnaSeqChars, 0, 3).toUpperCase() + .equals( + ResidueProperties.START)) + { + cdnaStart += 3; + cdnaLength -= 3; + } + + if (cdnaLength != mappedLength) + { + return null; + } + if (!translatesAs(cdnaSeqChars, cdnaStart - 1, aaSeqChars)) + { + return null; + } + MapList map = new MapList(new int[] + { cdnaStart, cdnaEnd }, new int[] + { proteinStart, proteinEnd }, 3, 1); + return map; + } + + /** + * Test whether the given cdna sequence, starting at the given offset, + * translates to the given amino acid sequence, using the standard translation + * table. Designed to fail fast i.e. as soon as a mismatch position is found. + * + * @param cdnaSeqChars + * @param cdnaStart + * @param aaSeqChars + * @return + */ + protected static boolean translatesAs(char[] cdnaSeqChars, int cdnaStart, + char[] aaSeqChars) + { + int aaResidue = 0; + for (int i = cdnaStart; i < cdnaSeqChars.length - 2 + && aaResidue < aaSeqChars.length; i += 3, aaResidue++) + { + String codon = String.valueOf(cdnaSeqChars, i, 3); + final String translated = ResidueProperties.codonTranslate( + codon); + /* + * ? allow X in protein to match untranslatable in dna ? + */ + final char aaRes = aaSeqChars[aaResidue]; + if ((translated == null || "STOP".equals(translated)) && aaRes == 'X') + { + continue; + } + if (translated == null + || !(aaRes == translated.charAt(0))) + { + // debug + // System.out.println(("Mismatch at " + i + "/" + aaResidue + ": " + // + codon + "(" + translated + ") != " + aaRes)); + return false; + } + } + // fail if we didn't match all of the aa sequence + return (aaResidue == aaSeqChars.length); + } + + /** + * Align sequence 'seq' to match the alignment of a mapped sequence. Note this + * currently assumes that we are aligning cDNA to match protein. + * + * @param seq + * the sequence to be realigned + * @param al + * the alignment whose sequence alignment is to be 'copied' + * @param gap + * character string represent a gap in the realigned sequence + * @param preserveUnmappedGaps + * @param preserveMappedGaps + * @return true if the sequence was realigned, false if it could not be + */ + public static boolean alignSequenceAs(SequenceI seq, AlignmentI al, + String gap, boolean preserveMappedGaps, + boolean preserveUnmappedGaps) + { + /* + * Get any mappings from the source alignment to the target (dataset) sequence. + */ + // TODO there may be one AlignedCodonFrame per dataset sequence, or one with + // all mappings. Would it help to constrain this? + List mappings = al.getCodonFrame(seq); + if (mappings == null || mappings.isEmpty()) + { + return false; + } + + /* + * Locate the aligned source sequence whose dataset sequence is mapped. We + * just take the first match here (as we can't align cDNA like more than one + * protein sequence). + */ + SequenceI alignFrom = null; + AlignedCodonFrame mapping = null; + for (AlignedCodonFrame mp : mappings) + { + alignFrom = mp.findAlignedSequence(seq.getDatasetSequence(), al); + if (alignFrom != null) + { + mapping = mp; + break; + } + } + + if (alignFrom == null) + { + return false; + } + alignSequenceAs(seq, alignFrom, mapping, gap, al.getGapCharacter(), + preserveMappedGaps, preserveUnmappedGaps); + return true; + } + + /** + * Align sequence 'alignTo' the same way as 'alignFrom', using the mapping to + * match residues and codons. Flags control whether existing gaps in unmapped + * (intron) and mapped (exon) regions are preserved or not. Gaps linking intro + * and exon are only retained if both flags are set. + * + * @param alignTo + * @param alignFrom + * @param mapping + * @param myGap + * @param sourceGap + * @param preserveUnmappedGaps + * @param preserveMappedGaps + */ + public static void alignSequenceAs(SequenceI alignTo, + SequenceI alignFrom, + AlignedCodonFrame mapping, String myGap, char sourceGap, + boolean preserveMappedGaps, boolean preserveUnmappedGaps) + { + // TODO generalise to work for Protein-Protein, dna-dna, dna-protein + final char[] thisSeq = alignTo.getSequence(); + final char[] thatAligned = alignFrom.getSequence(); + StringBuilder thisAligned = new StringBuilder(2 * thisSeq.length); + + // aligned and dataset sequence positions, all base zero + int thisSeqPos = 0; + int sourceDsPos = 0; + + int basesWritten = 0; + char myGapChar = myGap.charAt(0); + int ratio = myGap.length(); + + /* + * Traverse the aligned protein sequence. + */ + int sourceGapMappedLength = 0; + boolean inExon = false; + for (char sourceChar : thatAligned) + { + if (sourceChar == sourceGap) + { + sourceGapMappedLength += ratio; + continue; + } + + /* + * Found a residue. Locate its mapped codon (start) position. + */ + sourceDsPos++; + // Note mapping positions are base 1, our sequence positions base 0 + int[] mappedPos = mapping.getMappedRegion(alignTo, alignFrom, + sourceDsPos); + if (mappedPos == null) + { + /* + * Abort realignment if unmapped protein. Or could ignore it?? + */ + System.err.println("Can't align: no codon mapping to residue " + + sourceDsPos + "(" + sourceChar + ")"); + return; + } + + int mappedCodonStart = mappedPos[0]; // position (1...) of codon start + int mappedCodonEnd = mappedPos[mappedPos.length - 1]; // codon end pos + StringBuilder trailingCopiedGap = new StringBuilder(); + + /* + * Copy dna sequence up to and including this codon. Optionally, include + * gaps before the codon starts (in introns) and/or after the codon starts + * (in exons). + * + * Note this only works for 'linear' splicing, not reverse or interleaved. + * But then 'align dna as protein' doesn't make much sense otherwise. + */ + int intronLength = 0; + while (basesWritten < mappedCodonEnd && thisSeqPos < thisSeq.length) + { + final char c = thisSeq[thisSeqPos++]; + if (c != myGapChar) + { + basesWritten++; + + if (basesWritten < mappedCodonStart) + { + /* + * Found an unmapped (intron) base. First add in any preceding gaps + * (if wanted). + */ + if (preserveUnmappedGaps && trailingCopiedGap.length() > 0) + { + thisAligned.append(trailingCopiedGap.toString()); + intronLength += trailingCopiedGap.length(); + trailingCopiedGap = new StringBuilder(); + } + intronLength++; + inExon = false; + } + else + { + final boolean startOfCodon = basesWritten == mappedCodonStart; + int gapsToAdd = calculateGapsToInsert(preserveMappedGaps, + preserveUnmappedGaps, sourceGapMappedLength, inExon, + trailingCopiedGap.length(), intronLength, startOfCodon); + for (int i = 0; i < gapsToAdd; i++) + { + thisAligned.append(myGapChar); + } + sourceGapMappedLength = 0; + inExon = true; + } + thisAligned.append(c); + trailingCopiedGap = new StringBuilder(); + } + else + { + if (inExon && preserveMappedGaps) + { + trailingCopiedGap.append(myGapChar); + } + else if (!inExon && preserveUnmappedGaps) + { + trailingCopiedGap.append(myGapChar); + } + } + } + } + + /* + * At end of protein sequence. Copy any remaining dna sequence, optionally + * including (intron) gaps. We do not copy trailing gaps in protein. + */ + while (thisSeqPos < thisSeq.length) + { + final char c = thisSeq[thisSeqPos++]; + if (c != myGapChar || preserveUnmappedGaps) + { + thisAligned.append(c); + } + } + + /* + * All done aligning, set the aligned sequence. + */ + alignTo.setSequence(new String(thisAligned)); + } + + /** + * Helper method to work out how many gaps to insert when realigning. + * + * @param preserveMappedGaps + * @param preserveUnmappedGaps + * @param sourceGapMappedLength + * @param inExon + * @param trailingCopiedGap + * @param intronLength + * @param startOfCodon + * @return + */ + protected static int calculateGapsToInsert(boolean preserveMappedGaps, + boolean preserveUnmappedGaps, int sourceGapMappedLength, + boolean inExon, int trailingGapLength, + int intronLength, final boolean startOfCodon) + { + int gapsToAdd = 0; + if (startOfCodon) + { + /* + * Reached start of codon. Ignore trailing gaps in intron unless we are + * preserving gaps in both exon and intron. Ignore them anyway if the + * protein alignment introduces a gap at least as large as the intronic + * region. + */ + if (inExon && !preserveMappedGaps) + { + trailingGapLength = 0; + } + if (!inExon && !(preserveMappedGaps && preserveUnmappedGaps)) + { + trailingGapLength = 0; + } + if (inExon) + { + gapsToAdd = Math.max(sourceGapMappedLength, trailingGapLength); + } + else + { + if (intronLength + trailingGapLength <= sourceGapMappedLength) + { + gapsToAdd = sourceGapMappedLength - intronLength; + } + else + { + gapsToAdd = Math.min(intronLength + trailingGapLength + - sourceGapMappedLength, trailingGapLength); + } + } + } + else + { + /* + * second or third base of codon; check for any gaps in dna + */ + if (!preserveMappedGaps) + { + trailingGapLength = 0; + } + gapsToAdd = Math.max(sourceGapMappedLength, trailingGapLength); + } + return gapsToAdd; + } + + /** + * Returns a list of sequences mapped from the given sequences and aligned + * (gapped) in the same way. For example, the cDNA for aligned protein, where + * a single gap in protein generates three gaps in cDNA. + * + * @param sequences + * @param gapCharacter + * @param mappings + * @return + */ + public static List getAlignedTranslation( + List sequences, char gapCharacter, + Set mappings) + { + List alignedSeqs = new ArrayList(); + + for (SequenceI seq : sequences) + { + List mapped = getAlignedTranslation(seq, gapCharacter, + mappings); + alignedSeqs.addAll(mapped); + } + return alignedSeqs; + } + + /** + * Returns sequences aligned 'like' the source sequence, as mapped by the + * given mappings. Normally we expect zero or one 'mapped' sequences, but this + * will support 1-to-many as well. + * + * @param seq + * @param gapCharacter + * @param mappings + * @return + */ + protected static List getAlignedTranslation(SequenceI seq, + char gapCharacter, Set mappings) + { + List result = new ArrayList(); + for (AlignedCodonFrame mapping : mappings) + { + if (mapping.involvesSequence(seq)) + { + SequenceI mapped = getAlignedTranslation(seq, gapCharacter, mapping); + if (mapped != null) + { + result.add(mapped); + } + } + } + return result; + } + + /** + * Returns the translation of 'seq' (as held in the mapping) with + * corresponding alignment (gaps). + * + * @param seq + * @param gapCharacter + * @param mapping + * @return + */ + protected static SequenceI getAlignedTranslation(SequenceI seq, + char gapCharacter, AlignedCodonFrame mapping) + { + String gap = String.valueOf(gapCharacter); + boolean toDna = false; + int fromRatio = 1; + SequenceI mapTo = mapping.getDnaForAaSeq(seq); + if (mapTo != null) + { + // mapping is from protein to nucleotide + toDna = true; + // should ideally get gap count ratio from mapping + gap = String.valueOf(new char[] + { gapCharacter, gapCharacter, gapCharacter }); + } + else + { + // mapping is from nucleotide to protein + mapTo = mapping.getAaForDnaSeq(seq); + fromRatio = 3; + } + StringBuilder newseq = new StringBuilder(seq.getLength() + * (toDna ? 3 : 1)); + + int residueNo = 0; // in seq, base 1 + int[] phrase = new int[fromRatio]; + int phraseOffset = 0; + int gapWidth = 0; + boolean first = true; + final Sequence alignedSeq = new Sequence("", ""); + + for (char c : seq.getSequence()) + { + if (c == gapCharacter) + { + gapWidth++; + if (gapWidth >= fromRatio) + { + newseq.append(gap); + gapWidth = 0; + } + } + else + { + phrase[phraseOffset++] = residueNo + 1; + if (phraseOffset == fromRatio) + { + /* + * Have read a whole codon (or protein residue), now translate: map + * source phrase to positions in target sequence add characters at + * these positions to newseq Note mapping positions are base 1, our + * sequence positions base 0. + */ + SearchResults sr = new SearchResults(); + for (int pos : phrase) + { + mapping.markMappedRegion(seq, pos, sr); + } + newseq.append(sr.toString()); + if (first) + { + first = false; + // Hack: Copy sequence dataset, name and description from + // SearchResults.match[0].sequence + // TODO? carry over sequence names from original 'complement' + // alignment + SequenceI mappedTo = sr.getResultSequence(0); + alignedSeq.setName(mappedTo.getName()); + alignedSeq.setDescription(mappedTo.getDescription()); + alignedSeq.setDatasetSequence(mappedTo); + } + phraseOffset = 0; + } + residueNo++; + } + } + alignedSeq.setSequence(newseq.toString()); + return alignedSeq; + } + + /** + * Realigns the given protein to match the alignment of the dna, using codon + * mappings to translate aligned codon positions to protein residues. + * + * @param protein + * the alignment whose sequences are realigned by this method + * @param dna + * the dna alignment whose alignment we are 'copying' + * @return the number of sequences that were realigned + */ + public static int alignProteinAsDna(AlignmentI protein, AlignmentI dna) + { + Set mappings = protein.getCodonFrames(); + + /* + * Map will hold, for each aligned codon position e.g. [3, 5, 6], a map of + * {dnaSequence, {proteinSequence, codonProduct}} at that position. The + * comparator keeps the codon positions ordered. + */ + Map> alignedCodons = new TreeMap>( + new CodonComparator()); + for (SequenceI dnaSeq : dna.getSequences()) + { + for (AlignedCodonFrame mapping : mappings) + { + Mapping seqMap = mapping.getMappingForSequence(dnaSeq); + SequenceI prot = mapping.findAlignedSequence( + dnaSeq.getDatasetSequence(), protein); + if (prot != null) + { + addCodonPositions(dnaSeq, prot, protein.getGapCharacter(), + seqMap, alignedCodons); + } + } + } + return alignProteinAs(protein, alignedCodons); + } + + /** + * Update the aligned protein sequences to match the codon alignments given in + * the map. + * + * @param protein + * @param alignedCodons + * an ordered map of codon positions (columns), with sequence/peptide + * values present in each column + * @return + */ + protected static int alignProteinAs(AlignmentI protein, + Map> alignedCodons) + { + /* + * Prefill aligned sequences with gaps before inserting aligned protein + * residues. + */ + int alignedWidth = alignedCodons.size(); + char[] gaps = new char[alignedWidth]; + Arrays.fill(gaps, protein.getGapCharacter()); + String allGaps = String.valueOf(gaps); + for (SequenceI seq : protein.getSequences()) + { + seq.setSequence(allGaps); + } + + int column = 0; + for (AlignedCodon codon : alignedCodons.keySet()) + { + final Map columnResidues = alignedCodons.get(codon); + for (Entry entry : columnResidues + .entrySet()) + { + // place translated codon at its column position in sequence + entry.getKey().getSequence()[column] = entry.getValue().charAt(0); + } + column++; + } + return 0; + } + + /** + * Populate the map of aligned codons by traversing the given sequence + * mapping, locating the aligned positions of mapped codons, and adding those + * positions and their translation products to the map. + * + * @param dna + * the aligned sequence we are mapping from + * @param protein + * the sequence to be aligned to the codons + * @param gapChar + * the gap character in the dna sequence + * @param seqMap + * a mapping to a sequence translation + * @param alignedCodons + * the map we are building up + */ + static void addCodonPositions(SequenceI dna, SequenceI protein, + char gapChar, + Mapping seqMap, + Map> alignedCodons) + { + Iterator codons = seqMap.getCodonIterator(dna, gapChar); + while (codons.hasNext()) + { + AlignedCodon codon = codons.next(); + Map seqProduct = alignedCodons.get(codon); + if (seqProduct == null) + { + seqProduct = new HashMap(); + alignedCodons.put(codon, seqProduct); + } + seqProduct.put(protein, codon.product); + } + } + + /** + * Returns true if a cDNA/Protein mapping either exists, or could be made, + * between at least one pair of sequences in the two alignments. Currently, + * the logic is: + *
    + *
  • One alignment must be nucleotide, and the other protein
  • + *
  • At least one pair of sequences must be already mapped, or mappable
  • + *
  • Mappable means the nucleotide translation matches the protein sequence
  • + *
  • The translation may ignore start and stop codons if present in the + * nucleotide
  • + *
+ * + * @param al1 + * @param al2 + * @return + */ + public static boolean isMappable(AlignmentI al1, AlignmentI al2) + { + /* + * Require one nucleotide and one protein + */ + if (al1.isNucleotide() == al2.isNucleotide()) + { + return false; + } + AlignmentI dna = al1.isNucleotide() ? al1 : al2; + AlignmentI protein = dna == al1 ? al2 : al1; + Set mappings = protein.getCodonFrames(); + for (SequenceI dnaSeq : dna.getSequences()) + { + for (SequenceI proteinSeq : protein.getSequences()) + { + if (isMappable(dnaSeq, proteinSeq, mappings)) + { + return true; + } + } + } + return false; + } + + /** + * Returns true if the dna sequence is mapped, or could be mapped, to the + * protein sequence. + * + * @param dnaSeq + * @param proteinSeq + * @param mappings + * @return + */ + public static boolean isMappable(SequenceI dnaSeq, SequenceI proteinSeq, + Set mappings) + { + SequenceI dnaDs = dnaSeq.getDatasetSequence() == null ? dnaSeq : dnaSeq.getDatasetSequence(); + SequenceI proteinDs = proteinSeq.getDatasetSequence() == null ? proteinSeq + : proteinSeq.getDatasetSequence(); + + /* + * Already mapped? + */ + for (AlignedCodonFrame mapping : mappings) { + if ( proteinDs == mapping.getAaForDnaSeq(dnaDs)) { + return true; + } + } + + /* + * Just try to make a mapping (it is not yet stored), test whether + * successful. + */ + return mapProteinToCdna(proteinDs, dnaDs) != null; + } + + /** + * Finds any reference annotations associated with the sequences in + * sequenceScope, that are not already added to the alignment, and adds them + * to the 'candidates' map. Also populates a lookup table of annotation + * labels, keyed by calcId, for use in constructing tooltips or the like. + * + * @param sequenceScope + * the sequences to scan for reference annotations + * @param labelForCalcId + * (optional) map to populate with label for calcId + * @param candidates + * map to populate with annotations for sequence + * @param al + * the alignment to check for presence of annotations + */ + public static void findAddableReferenceAnnotations( + List sequenceScope, Map labelForCalcId, + final Map> candidates, + AlignmentI al) + { + if (sequenceScope == null) + { + return; + } + + /* + * For each sequence in scope, make a list of any annotations on the + * underlying dataset sequence which are not already on the alignment. + * + * Add to a map of { alignmentSequence, } + */ + for (SequenceI seq : sequenceScope) + { + SequenceI dataset = seq.getDatasetSequence(); + if (dataset == null) + { + continue; + } + AlignmentAnnotation[] datasetAnnotations = dataset.getAnnotation(); + if (datasetAnnotations == null) + { + continue; + } + final List result = new ArrayList(); + for (AlignmentAnnotation dsann : datasetAnnotations) + { + /* + * Find matching annotations on the alignment. If none is found, then + * add this annotation to the list of 'addable' annotations for this + * sequence. + */ + final Iterable matchedAlignmentAnnotations = al + .findAnnotations(seq, dsann.getCalcId(), + dsann.label); + if (!matchedAlignmentAnnotations.iterator().hasNext()) + { + result.add(dsann); + if (labelForCalcId != null) + { + labelForCalcId.put(dsann.getCalcId(), dsann.label); + } + } + } + /* + * Save any addable annotations for this sequence + */ + if (!result.isEmpty()) + { + candidates.put(seq, result); + } + } + } + + /** + * Adds annotations to the top of the alignment annotations, in the same order + * as their related sequences. + * + * @param annotations + * the annotations to add + * @param alignment + * the alignment to add them to + * @param selectionGroup + * current selection group (or null if none) + */ + public static void addReferenceAnnotations( + Map> annotations, + final AlignmentI alignment, final SequenceGroup selectionGroup) + { + for (SequenceI seq : annotations.keySet()) + { + for (AlignmentAnnotation ann : annotations.get(seq)) + { + AlignmentAnnotation copyAnn = new AlignmentAnnotation(ann); + int startRes = 0; + int endRes = ann.annotations.length; + if (selectionGroup != null) + { + startRes = selectionGroup.getStartRes(); + endRes = selectionGroup.getEndRes(); + } + copyAnn.restrict(startRes, endRes); + + /* + * Add to the sequence (sets copyAnn.datasetSequence), unless the + * original annotation is already on the sequence. + */ + if (!seq.hasAnnotation(ann)) + { + seq.addAlignmentAnnotation(copyAnn); + } + // adjust for gaps + copyAnn.adjustForAlignment(); + // add to the alignment and set visible + alignment.addAnnotation(copyAnn); + copyAnn.visible = true; + } + } + } + + /** + * Set visibility of alignment annotations of specified types (labels), for + * specified sequences. This supports controls like + * "Show all secondary structure", "Hide all Temp factor", etc. + * + * @al the alignment to scan for annotations + * @param types + * the types (labels) of annotations to be updated + * @param forSequences + * if not null, only annotations linked to one of these sequences are + * in scope for update; if null, acts on all sequence annotations + * @param anyType + * if this flag is true, 'types' is ignored (label not checked) + * @param doShow + * if true, set visibility on, else set off + */ + public static void showOrHideSequenceAnnotations(AlignmentI al, + Collection types, List forSequences, + boolean anyType, boolean doShow) + { + for (AlignmentAnnotation aa : al + .getAlignmentAnnotation()) + { + if (anyType || types.contains(aa.label)) + { + if ((aa.sequenceRef != null) + && (forSequences == null || forSequences + .contains(aa.sequenceRef))) + { + aa.visible = doShow; + } + } + } + } } diff --git a/src/jalview/analysis/CodingUtils.java b/src/jalview/analysis/CodingUtils.java new file mode 100644 index 0000000..a434465 --- /dev/null +++ b/src/jalview/analysis/CodingUtils.java @@ -0,0 +1,119 @@ +package jalview.analysis; + +/** + * A utility class to provide encoding/decoding schemes for data. + * + * @author gmcarstairs + * + */ +public class CodingUtils +{ + + /* + * Number of bits used when encoding codon characters. 2 is enough for ACGT. + * To accommodate more (e.g. ambiguity codes), simply increase this number + * (and adjust unit tests to match). + */ + private static final int CODON_ENCODING_BITSHIFT = 2; + + /** + * Encode a codon from e.g. ['A', 'G', 'C'] to a number in the range 0 - 63. + * Converts lower to upper case, U to T, then assembles a binary value by + * encoding A/C/G/T as 00/01/10/11 respectively and shifting. + * + * @param codon + * @return the encoded codon, or a negative number if unexpected characters + * found + */ + public static int encodeCodon(char[] codon) + { + if (codon == null) + { + return -1; + } + return encodeCodon(codon[2]) + + (encodeCodon(codon[1]) << CODON_ENCODING_BITSHIFT) + + (encodeCodon(codon[0]) << (2 * CODON_ENCODING_BITSHIFT)); + } + + /** + * Encodes aA/cC/gG/tTuU as 0/1/2/3 respectively. Returns Integer.MIN_VALUE (a + * large negative value) for any other character. + * + * @param c + * @return + */ + public static int encodeCodon(char c) + { + int result = Integer.MIN_VALUE; + switch (c) + { + case 'A': + case 'a': + result = 0; + break; + case 'C': + case 'c': + result = 1; + break; + case 'G': + case 'g': + result = 2; + break; + case 'T': + case 't': + case 'U': + case 'u': + result = 3; + break; + } + return result; + } + + /** + * Converts a binary encoded codon into an ['A', 'C', 'G'] (or 'T') triplet. + * + * The two low-order bits encode for A/C/G/T as 0/1/2/3, etc. + * + * @param encoded + * @return + */ + public static char[] decodeCodon(int encoded) + { + char[] result = new char[3]; + result[2] = decodeNucleotide(encoded & 3); + encoded = encoded >>> CODON_ENCODING_BITSHIFT; + result[1] = decodeNucleotide(encoded & 3); + encoded = encoded >>> CODON_ENCODING_BITSHIFT; + result[0] = decodeNucleotide(encoded & 3); + return result; + } + + /** + * Convert value 0/1/2/3 to 'A'/'C'/'G'/'T' + * + * @param i + * @return + */ + public static char decodeNucleotide(int i) + { + char result = '0'; + switch (i) + { + case 0: + result = 'A'; + break; + case 1: + result = 'C'; + break; + case 2: + result = 'G'; + break; + case 3: + result = 'T'; + break; + } + return result; + } + +} diff --git a/src/jalview/analysis/CodonComparator.java b/src/jalview/analysis/CodonComparator.java new file mode 100644 index 0000000..fc196de --- /dev/null +++ b/src/jalview/analysis/CodonComparator.java @@ -0,0 +1,91 @@ +package jalview.analysis; + +import jalview.datamodel.AlignedCodon; + +import java.util.Comparator; + +/** + * Implements rules for comparing two aligned codons, i.e. determining whether + * they should occupy the same position in a translated protein alignment, or + * one or the other should 'follow' (by preceded by a gap). + * + * @author gmcarstairs + * + */ +public final class CodonComparator implements Comparator +{ + + @Override + public int compare(AlignedCodon ac1, AlignedCodon ac2) + { + if (ac1 == null || ac2 == null || ac1.equals(ac2)) + { + return 0; + } + + /** + *
+     * Case 1: if one starts before the other, and doesn't end after it, then it
+     * precedes. We ignore the middle base position here.
+     * A--GT
+     * -CT-G
+     * 
+ */ + if (ac1.pos1 < ac2.pos1 && ac1.pos3 <= ac2.pos3) + { + return -1; + } + if (ac2.pos1 < ac1.pos1 && ac2.pos3 <= ac1.pos3) + { + return 1; + } + + /** + *
+     * Case 2: if one ends after the other, and doesn't start before it, then it
+     * follows. We ignore the middle base position here.
+     * -TG-A
+     * G-TC
+     * 
+ */ + if (ac1.pos3 > ac2.pos3 && ac1.pos1 >= ac2.pos1) + { + return 1; + } + if (ac2.pos3 > ac1.pos3 && ac2.pos1 >= ac1.pos1) + { + return -1; + } + + /* + * Case 3: if start and end match, compare middle base positions. + */ + if (ac1.pos1 == ac2.pos1 && ac1.pos3 == ac2.pos3) + { + return Integer.compare(ac1.pos2, ac2.pos2); + } + + /* + * That just leaves the 'enclosing' case - one codon starts after but ends + * before the other. If the middle bases don't match, use their comparison + * (majority vote). + */ + int compareMiddles = Integer.compare(ac1.pos2, ac2.pos2); + if (compareMiddles != 0) + { + return compareMiddles; + } + + /** + *
+     * Finally just leaves overlap with matching middle base, e.g. 
+     * -A-A-A
+     * G--GG 
+     * In this case the choice is arbitrary whether to compare based on
+     * first or last base position. We pick the first. Note this preserves
+     * symmetricality of the comparison.
+     * 
+ */ + return Integer.compare(ac1.pos1, ac2.pos1); + } +} diff --git a/src/jalview/analysis/CrossRef.java b/src/jalview/analysis/CrossRef.java index f34b822..eed2d7e 100644 --- a/src/jalview/analysis/CrossRef.java +++ b/src/jalview/analysis/CrossRef.java @@ -20,21 +20,21 @@ */ package jalview.analysis; -import java.util.Enumeration; -import java.util.List; -import java.util.Vector; -import java.util.Hashtable; - import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentI; -import jalview.datamodel.DBRefSource; import jalview.datamodel.DBRefEntry; +import jalview.datamodel.DBRefSource; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; import jalview.ws.SequenceFetcher; import jalview.ws.seqfetcher.ASequenceFetcher; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.List; +import java.util.Vector; + /** * Functions for cross-referencing sequence databases. user must first specify * if cross-referencing from protein or dna (set dna==true) @@ -230,7 +230,7 @@ public class CrossRef { Vector rseqs = new Vector(); Alignment ral = null; - AlignedCodonFrame cf = new AlignedCodonFrame(0); // nominal width + AlignedCodonFrame cf = new AlignedCodonFrame(); // nominal width for (int s = 0; s < seqs.length; s++) { SequenceI dss = seqs[s]; @@ -258,7 +258,9 @@ public class CrossRef for (int r = 0; xrfs != null && r < xrfs.length; r++) { if (source != null && !source.equals(xrfs[r].getSource())) + { continue; + } if (xrfs[r].hasMap()) { if (xrfs[r].getMap().getTo() != null) @@ -291,7 +293,9 @@ public class CrossRef { found |= searchDataset(dss, xrfs[r], dataset, rseqs, cf); // ,false,!dna); if (found) + { xrfs[r] = null; // we've recovered seqs for this one. + } } } } @@ -328,7 +332,9 @@ public class CrossRef for (int r = 0; r < xrfs.length; r++) { if (xrfs[r] != null) + { t[l++] = xrfs[r]; + } } xrfs = t; try @@ -432,7 +438,9 @@ public class CrossRef { boolean found = false; if (lrfs == null) + { return false; + } for (int i = 0; i < lrfs.length; i++) { DBRefEntry xref = new DBRefEntry(lrfs[i]); @@ -484,7 +492,9 @@ public class CrossRef boolean found = false; SequenceI[] typer = new SequenceI[1]; if (dataset == null) + { return false; + } if (dataset.getSequences() == null) { System.err.println("Empty dataset sequence set - NO VECTOR"); @@ -494,6 +504,7 @@ public class CrossRef synchronized (ds = dataset.getSequences()) { for (SequenceI nxt : ds) + { if (nxt != null) { if (nxt.getDatasetSequence() != null) @@ -566,11 +577,55 @@ public class CrossRef } } + } } return found; } /** + * Returns true if either sequence has a cross-reference to the other + * + * @param seq1 + * @param seq2 + * @return + */ + public static boolean haveCrossRef(SequenceI seq1, SequenceI seq2) + { + return hasCrossRef(seq1, seq2) || hasCrossRef(seq2, seq1); + } + + /** + * Returns true if seq1 has a cross-reference to seq2. Currently this assumes + * that sequence name is structured as Source|AccessId. + * + * @param seq1 + * @param seq2 + * @return + */ + public static boolean hasCrossRef(SequenceI seq1, SequenceI seq2) + { + if (seq1 == null || seq2 == null) + { + return false; + } + String name = seq2.getName(); + final DBRefEntry[] xrefs = seq1.getDBRef(); + if (xrefs != null) + { + for (DBRefEntry xref : xrefs) + { + String xrefName = xref.getSource() + "|" + xref.getAccessionId(); + // case-insensitive test, consistent with DBRefEntry.equalRef() + if (xrefName.equalsIgnoreCase(name)) + { + return true; + } + } + } + return false; + } + + /** * precalculate different products that can be found for seqs in dataset and * return them. * diff --git a/src/jalview/analysis/Dna.java b/src/jalview/analysis/Dna.java index 00793be..ab606f7 100644 --- a/src/jalview/analysis/Dna.java +++ b/src/jalview/analysis/Dna.java @@ -20,120 +20,157 @@ */ package jalview.analysis; -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.Vector; - +import jalview.api.AlignViewportI; +import jalview.bin.Cache; +import jalview.datamodel.AlignedCodon; import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.Annotation; import jalview.datamodel.DBRefEntry; +import jalview.datamodel.DBRefSource; import jalview.datamodel.FeatureProperties; +import jalview.datamodel.GraphLine; import jalview.datamodel.Mapping; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.schemes.ResidueProperties; +import jalview.util.Comparison; +import jalview.util.DBRefUtils; import jalview.util.MapList; import jalview.util.ShiftList; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + public class Dna { - /** + private static final String STOP_X = "X"; + + private static final Comparator comparator = new CodonComparator(); + + /* + * 'final' variables describe the inputs to the translation, which should not + * be modified. + */ + final private List selection; + + final private String[] seqstring; + + final private int[] contigs; + + final private char gapChar; + + final private AlignmentAnnotation[] annotations; + + final private int dnaWidth; + + final private Alignment dataset; + + /* + * Working variables for the translation. * - * @param cdp1 - * @param cdp2 - * @return -1 if cdp1 aligns before cdp2, 0 if in the same column or cdp2 is - * null, +1 if after cdp2 + * The width of the translation-in-progress protein alignment. */ - private static int compare_codonpos(int[] cdp1, int[] cdp2) - { - if (cdp2 == null - || (cdp1[0] == cdp2[0] && cdp1[1] == cdp2[1] && cdp1[2] == cdp2[2])) - return 0; - if (cdp1[0] < cdp2[0] || cdp1[1] < cdp2[1] || cdp1[2] < cdp2[2]) - return -1; // one base in cdp1 precedes the corresponding base in the - // other codon - return 1; // one base in cdp1 appears after the corresponding base in the - // other codon. - } + private int aaWidth = 0; - /** - * DNA->mapped protein sequence alignment translation given set of sequences - * 1. id distinct coding regions within selected region for each sequence 2. - * generate peptides based on inframe (or given) translation or (optionally - * and where specified) out of frame translations (annotated appropriately) 3. - * align peptides based on codon alignment + /* + * This array will be built up so that position i holds the codon positions + * e.g. [7, 9, 10] that match column i (base 0) in the aligned translation. + * Note this implies a contract that if two codons do not align exactly, their + * translated products must occupy different column positions. */ + private AlignedCodon[] alignedCodons; + /** - * id potential products from dna 1. search for distinct products within - * selected region for each selected sequence 2. group by associated DB type. - * 3. return as form for input into above function + * Constructor given a viewport and the visible contigs. + * + * @param viewport + * @param visibleContigs */ + public Dna(AlignViewportI viewport, int[] visibleContigs) + { + this.selection = Arrays.asList(viewport.getSequenceSelection()); + this.seqstring = viewport.getViewAsString(true); + this.contigs = visibleContigs; + this.gapChar = viewport.getGapCharacter(); + this.annotations = viewport.getAlignment().getAlignmentAnnotation(); + this.dnaWidth = viewport.getAlignment().getWidth(); + this.dataset = viewport.getAlignment().getDataset(); + } + /** + * Test whether codon positions cdp1 should align before, with, or after cdp2. + * Returns zero if all positions match (or either argument is null). Returns + * -1 if any position in the first codon precedes the corresponding position + * in the second codon. Else returns +1 (some position in the second codon + * precedes the corresponding position in the first). + * + * Note this is not necessarily symmetric, for example: + *
    + *
  • compareCodonPos([2,5,6], [3,4,5]) returns -1
  • + *
  • compareCodonPos([3,4,5], [2,5,6]) also returns -1
  • + *
* + * @param ac1 + * @param ac2 + * @return */ + public static final int compareCodonPos(AlignedCodon ac1, AlignedCodon ac2) + { + return comparator.compare(ac1, ac2); + // return jalview_2_8_2compare(ac1, ac2); + } + /** - * create a new alignment of protein sequences by an inframe translation of - * the provided NA sequences + * Codon comparison up to Jalview 2.8.2. This rule is sequence order dependent + * - see http://issues.jalview.org/browse/JAL-1635 * - * @param selection - * @param seqstring - * @param viscontigs - * @param gapCharacter - * @param annotations - * @param aWidth - * @param dataset - * destination dataset for translated sequences and mappings + * @param ac1 + * @param ac2 * @return */ - public static AlignmentI CdnaTranslate(SequenceI[] selection, - String[] seqstring, int viscontigs[], char gapCharacter, - AlignmentAnnotation[] annotations, int aWidth, Alignment dataset) + private static int jalview_2_8_2compare(AlignedCodon ac1, AlignedCodon ac2) { - return CdnaTranslate(selection, seqstring, null, viscontigs, - gapCharacter, annotations, aWidth, dataset); + if (ac1 == null || ac2 == null || (ac1.equals(ac2))) + { + return 0; + } + if (ac1.pos1 < ac2.pos1 || ac1.pos2 < ac2.pos2 || ac1.pos3 < ac2.pos3) + { + // one base in cdp1 precedes the corresponding base in the other codon + return -1; + } + // one base in cdp1 appears after the corresponding base in the other codon. + return 1; } /** * - * @param selection - * @param seqstring - * @param product - * - array of DbRefEntry objects from which exon map in seqstring is - * derived - * @param viscontigs - * @param gapCharacter - * @param annotations - * @param aWidth - * @param dataset * @return */ - public static AlignmentI CdnaTranslate(SequenceI[] selection, - String[] seqstring, DBRefEntry[] product, int viscontigs[], - char gapCharacter, AlignmentAnnotation[] annotations, int aWidth, - Alignment dataset) + public AlignmentI translateCdna() { - AlignedCodonFrame codons = new AlignedCodonFrame(aWidth); // stores hash of - // subsequent - // positions for - // each codon - // start position - // in alignment - int s, sSize = selection.length; - Vector pepseqs = new Vector(); + AlignedCodonFrame acf = new AlignedCodonFrame(); + + alignedCodons = new AlignedCodon[dnaWidth]; + + int s; + int sSize = selection.size(); + List pepseqs = new ArrayList(); for (s = 0; s < sSize; s++) { - SequenceI newseq = translateCodingRegion(selection[s], seqstring[s], - viscontigs, codons, gapCharacter, - (product != null) ? product[s] : null, false); // possibly - // anonymous - // product + SequenceI newseq = translateCodingRegion(selection.get(s), + seqstring[s], acf, pepseqs); + if (newseq != null) { - pepseqs.addElement(newseq); + pepseqs.add(newseq); SequenceI ds = newseq; if (dataset != null) { @@ -145,15 +182,15 @@ public class Dna } } } - if (codons.aaWidth == 0) - return null; - SequenceI[] newseqs = new SequenceI[pepseqs.size()]; - pepseqs.copyInto(newseqs); + + SequenceI[] newseqs = pepseqs.toArray(new SequenceI[pepseqs.size()]); AlignmentI al = new Alignment(newseqs); - al.padGaps(); // ensure we look aligned. + // ensure we look aligned. + al.padGaps(); + // link the protein translation to the DNA dataset al.setDataset(dataset); - translateAlignedAnnotations(annotations, al, codons); - al.addCodonFrame(codons); + translateAlignedAnnotations(al, acf); + al.addCodonFrame(acf); return al; } @@ -172,14 +209,13 @@ public class Dna for (int gd = 0; gd < selection.length; gd++) { SequenceI dna = selection[gd]; - jalview.datamodel.DBRefEntry[] dnarefs = jalview.util.DBRefUtils + DBRefEntry[] dnarefs = DBRefUtils .selectRefs(dna.getDBRef(), jalview.datamodel.DBRefSource.DNACODINGDBS); if (dnarefs != null) { // intersect with pep - // intersect with pep - Vector mappedrefs = new Vector(); + List mappedrefs = new ArrayList(); DBRefEntry[] refs = dna.getDBRef(); for (int d = 0; d < refs.length; d++) { @@ -187,11 +223,10 @@ public class Dna && refs[d].getMap().getMap().getFromRatio() == 3 && refs[d].getMap().getMap().getToRatio() == 1) { - mappedrefs.addElement(refs[d]); // add translated protein maps + mappedrefs.add(refs[d]); // add translated protein maps } } - dnarefs = new DBRefEntry[mappedrefs.size()]; - mappedrefs.copyInto(dnarefs); + dnarefs = mappedrefs.toArray(new DBRefEntry[mappedrefs.size()]); for (int d = 0; d < dnarefs.length; d++) { Mapping mp = dnarefs[d].getMap(); @@ -214,176 +249,107 @@ public class Dna } /** - * generate a set of translated protein products from annotated sequenceI + * Translate nucleotide alignment annotations onto translated amino acid + * alignment using codon mapping codons * - * @param selection - * @param viscontigs - * @param gapCharacter - * @param dataset - * destination dataset for translated sequences - * @param annotations - * @param aWidth - * @return - */ - public static AlignmentI CdnaTranslate(SequenceI[] selection, - int viscontigs[], char gapCharacter, Alignment dataset) - { - int alwidth = 0; - Vector cdnasqs = new Vector(); - Vector cdnasqi = new Vector(); - Vector cdnaprod = new Vector(); - for (int gd = 0; gd < selection.length; gd++) - { - SequenceI dna = selection[gd]; - jalview.datamodel.DBRefEntry[] dnarefs = jalview.util.DBRefUtils - .selectRefs(dna.getDBRef(), - jalview.datamodel.DBRefSource.DNACODINGDBS); - if (dnarefs != null) - { - // intersect with pep - Vector mappedrefs = new Vector(); - DBRefEntry[] refs = dna.getDBRef(); - for (int d = 0; d < refs.length; d++) - { - if (refs[d].getMap() != null && refs[d].getMap().getMap() != null - && refs[d].getMap().getMap().getFromRatio() == 3 - && refs[d].getMap().getMap().getToRatio() == 1) - { - mappedrefs.addElement(refs[d]); // add translated protein maps - } - } - dnarefs = new DBRefEntry[mappedrefs.size()]; - mappedrefs.copyInto(dnarefs); - for (int d = 0; d < dnarefs.length; d++) - { - Mapping mp = dnarefs[d].getMap(); - StringBuffer sqstr = new StringBuffer(); - if (mp != null) - { - Mapping intersect = mp.intersectVisContigs(viscontigs); - // generate seqstring for this sequence based on mapping - - if (sqstr.length() > alwidth) - alwidth = sqstr.length(); - cdnasqs.addElement(sqstr.toString()); - cdnasqi.addElement(dna); - cdnaprod.addElement(intersect); - } - } - } - SequenceI[] cdna = new SequenceI[cdnasqs.size()]; - DBRefEntry[] prods = new DBRefEntry[cdnaprod.size()]; - String[] xons = new String[cdnasqs.size()]; - cdnasqs.copyInto(xons); - cdnaprod.copyInto(prods); - cdnasqi.copyInto(cdna); - return CdnaTranslate(cdna, xons, prods, viscontigs, gapCharacter, - null, alwidth, dataset); - } - return null; - } - - /** - * translate na alignment annotations onto translated amino acid alignment al - * using codon mapping codons - * - * @param annotations * @param al - * @param codons + * the translated protein alignment */ - public static void translateAlignedAnnotations( - AlignmentAnnotation[] annotations, AlignmentI al, - AlignedCodonFrame codons) + protected void translateAlignedAnnotations(AlignmentI al, + AlignedCodonFrame acf) { - // ////////////////////////////// - // Copy annotations across - // // Can only do this for columns with consecutive codons, or where // annotation is sequence associated. - int pos, a, aSize; if (annotations != null) { - for (int i = 0; i < annotations.length; i++) + for (AlignmentAnnotation annotation : annotations) { - // Skip any autogenerated annotation - if (annotations[i].autoCalculated) + /* + * Skip hidden or autogenerated annotation. Also (for now), RNA + * secondary structure annotation. If we want to show this against + * protein we need a smarter way to 'translate' without generating + * invalid (unbalanced) structure annotation. + */ + if (annotation.autoCalculated || !annotation.visible + || annotation.isRNA()) { continue; } - aSize = codons.getaaWidth(); // aa alignment width. - jalview.datamodel.Annotation[] anots = (annotations[i].annotations == null) ? null - : new jalview.datamodel.Annotation[aSize]; + int aSize = aaWidth; + Annotation[] anots = (annotation.annotations == null) ? null + : new Annotation[aSize]; if (anots != null) { - for (a = 0; a < aSize; a++) + for (int a = 0; a < aSize; a++) { // process through codon map. - if (codons.codons[a] != null - && codons.codons[a][0] == (codons.codons[a][2] - 2)) + if (a < alignedCodons.length && alignedCodons[a] != null + && alignedCodons[a].pos1 == (alignedCodons[a].pos3 - 2)) { - anots[a] = getCodonAnnotation(codons.codons[a], - annotations[i].annotations); + anots[a] = getCodonAnnotation(alignedCodons[a], + annotation.annotations); } } } - jalview.datamodel.AlignmentAnnotation aa = new jalview.datamodel.AlignmentAnnotation( - annotations[i].label, annotations[i].description, anots); - aa.graph = annotations[i].graph; - aa.graphGroup = annotations[i].graphGroup; - aa.graphHeight = annotations[i].graphHeight; - if (annotations[i].getThreshold() != null) + AlignmentAnnotation aa = new AlignmentAnnotation(annotation.label, + annotation.description, anots); + aa.graph = annotation.graph; + aa.graphGroup = annotation.graphGroup; + aa.graphHeight = annotation.graphHeight; + if (annotation.getThreshold() != null) { - aa.setThreshold(new jalview.datamodel.GraphLine(annotations[i] + aa.setThreshold(new GraphLine(annotation .getThreshold())); } - if (annotations[i].hasScore) + if (annotation.hasScore) { - aa.setScore(annotations[i].getScore()); + aa.setScore(annotation.getScore()); } - if (annotations[i].sequenceRef != null) + + final SequenceI seqRef = annotation.sequenceRef; + if (seqRef != null) { - SequenceI aaSeq = codons - .getAaForDnaSeq(annotations[i].sequenceRef); + SequenceI aaSeq = acf.getAaForDnaSeq(seqRef); if (aaSeq != null) { // aa.compactAnnotationArray(); // throw away alignment annotation // positioning aa.setSequenceRef(aaSeq); - aa.createSequenceMapping(aaSeq, aaSeq.getStart(), true); // rebuild - // mapping + // rebuild mapping + aa.createSequenceMapping(aaSeq, aaSeq.getStart(), true); aa.adjustForAlignment(); aaSeq.addAlignmentAnnotation(aa); } - } al.addAnnotation(aa); } } } - private static Annotation getCodonAnnotation(int[] is, + private static Annotation getCodonAnnotation(AlignedCodon is, Annotation[] annotations) { // Have a look at all the codon positions for annotation and put the first // one found into the translated annotation pos. int contrib = 0; Annotation annot = null; - for (int p = 0; p < 3; p++) + for (int p = 1; p <= 3; p++) { - if (annotations[is[p]] != null) + int dnaCol = is.getBaseColumn(p); + if (annotations[dnaCol] != null) { if (annot == null) { - annot = new Annotation(annotations[is[p]]); + annot = new Annotation(annotations[dnaCol]); contrib = 1; } else { // merge with last - Annotation cpy = new Annotation(annotations[is[p]]); + Annotation cpy = new Annotation(annotations[dnaCol]); if (annot.colour == null) { annot.colour = cpy.colour; @@ -407,7 +373,7 @@ public class Dna } if (contrib > 1) { - annot.value /= (float) contrib; + annot.value /= contrib; } return annot; } @@ -419,92 +385,72 @@ public class Dna * sequence displayed under viscontigs visible columns * @param seqstring * ORF read in some global alignment reference frame - * @param viscontigs - * mapping from global reference frame to visible seqstring ORF read - * @param codons - * Definition of global ORF alignment reference frame - * @param gapCharacter - * @return sequence ready to be added to alignment. - * @deprecated Use - * {@link #translateCodingRegion(SequenceI,String,int[],AlignedCodonFrame,char,DBRefEntry,boolean)} - * instead - */ - public static SequenceI translateCodingRegion(SequenceI selection, - String seqstring, int[] viscontigs, AlignedCodonFrame codons, - char gapCharacter, DBRefEntry product) - { - return translateCodingRegion(selection, seqstring, viscontigs, codons, - gapCharacter, product, false); - } - - /** - * Translate a na sequence - * - * @param selection - * sequence displayed under viscontigs visible columns - * @param seqstring - * ORF read in some global alignment reference frame - * @param viscontigs - * mapping from global reference frame to visible seqstring ORF read - * @param codons + * @param acf * Definition of global ORF alignment reference frame - * @param gapCharacter - * @param starForStop - * when true stop codons will translate as '*', otherwise as 'X' + * @param proteinSeqs * @return sequence ready to be added to alignment. */ - public static SequenceI translateCodingRegion(SequenceI selection, - String seqstring, int[] viscontigs, AlignedCodonFrame codons, - char gapCharacter, DBRefEntry product, final boolean starForStop) + protected SequenceI translateCodingRegion(SequenceI selection, + String seqstring, AlignedCodonFrame acf, + List proteinSeqs) { - java.util.List skip = new ArrayList(); + List skip = new ArrayList(); int skipint[] = null; ShiftList vismapping = new ShiftList(); // map from viscontigs to seqstring // intervals - int vc, scontigs[] = new int[viscontigs.length]; + int vc; + int[] scontigs = new int[contigs.length]; int npos = 0; - for (vc = 0; vc < viscontigs.length; vc += 2) + for (vc = 0; vc < contigs.length; vc += 2) { if (vc == 0) { - vismapping.addShift(npos, viscontigs[vc]); + vismapping.addShift(npos, contigs[vc]); } else { // hidden region - vismapping.addShift(npos, viscontigs[vc] - viscontigs[vc - 1] + 1); + vismapping.addShift(npos, contigs[vc] - contigs[vc - 1] + 1); } - scontigs[vc] = viscontigs[vc]; - scontigs[vc + 1] = viscontigs[vc + 1]; + scontigs[vc] = contigs[vc]; + scontigs[vc + 1] = contigs[vc + 1]; } - StringBuffer protein = new StringBuffer(); - String seq = seqstring.replace('U', 'T'); + // allocate a roughly sized buffer for the protein sequence + StringBuilder protein = new StringBuilder(seqstring.length() / 2); + String seq = seqstring.replace('U', 'T').replace('u', 'T'); char codon[] = new char[3]; - int cdp[] = new int[3], rf = 0, lastnpos = 0, nend; + int cdp[] = new int[3]; + int rf = 0; + int lastnpos = 0; + int nend; int aspos = 0; int resSize = 0; for (npos = 0, nend = seq.length(); npos < nend; npos++) { - if (!jalview.util.Comparison.isGap(seq.charAt(npos))) + if (!Comparison.isGap(seq.charAt(npos))) { cdp[rf] = npos; // store position codon[rf++] = seq.charAt(npos); // store base } - // filled an RF yet ? if (rf == 3) { + /* + * Filled up a reading frame... + */ + AlignedCodon alignedCodon = new AlignedCodon(cdp[0], cdp[1], cdp[2]); String aa = ResidueProperties.codonTranslate(new String(codon)); rf = 0; + final String gapString = String.valueOf(gapChar); if (aa == null) { - aa = String.valueOf(gapCharacter); + aa = gapString; if (skipint == null) { skipint = new int[] - { cdp[0], cdp[2] }; + { alignedCodon.pos1, alignedCodon.pos3 /* cdp[0], cdp[2] */}; } - skipint[1] = cdp[2]; + skipint[1] = alignedCodon.pos3; // cdp[2]; } else { @@ -599,52 +545,66 @@ public class Dna } if (aa.equals("STOP")) { - aa = starForStop ? "*" : "X"; + aa = STOP_X; } resSize++; } - // insert/delete gaps prior to this codon - if necessary boolean findpos = true; while (findpos) { - // first ensure that the codons array is long enough. - codons.checkCodonFrameWidth(aspos); - // now check to see if we place the aa at the current aspos in the - // protein alignment - switch (Dna.compare_codonpos(cdp, codons.codons[aspos])) + /* + * Compare this codon's base positions with those currently aligned to + * this column in the translation. + */ + final int compareCodonPos = compareCodonPos(alignedCodon, + alignedCodons[aspos]); + switch (compareCodonPos) { case -1: - codons.insertAAGap(aspos, gapCharacter); + + /* + * This codon should precede the mapped positions - need to insert a + * gap in all prior sequences. + */ + insertAAGap(aspos, proteinSeqs); findpos = false; break; + case +1: - // this aa appears after the aligned codons at aspos, so prefix it - // with a gap - aa = "" + gapCharacter + aa; + + /* + * This codon belongs after the aligned codons at aspos. Prefix it + * with a gap and try the next position. + */ + aa = gapString + aa; aspos++; - // if (aspos >= codons.aaWidth) - // codons.aaWidth = aspos + 1; - break; // check the next position for alignment + break; + case 0: - // codon aligns at aspos position. + + /* + * Exact match - codon 'belongs' at this translated position. + */ findpos = false; } } - // codon aligns with all other sequence residues found at aspos protein.append(aa); lastnpos = npos; - if (codons.codons[aspos] == null) + if (alignedCodons[aspos] == null) { // mark this column as aligning to this aligned reading frame - codons.codons[aspos] = new int[] - { cdp[0], cdp[1], cdp[2] }; + alignedCodons[aspos] = alignedCodon; + } + else if (!alignedCodons[aspos].equals(alignedCodon)) + { + throw new IllegalStateException("Tried to coalign " + + alignedCodons[aspos].toString() + " with " + + alignedCodon.toString()); } - if (aspos >= codons.aaWidth) + if (aspos >= aaWidth) { // update maximum alignment width - // (we can do this without calling checkCodonFrameWidth because it was - // already done above) - codons.setAaWidth(aspos); + aaWidth = aspos; } // ready for next translated reading frame alignment position (if any) aspos++; @@ -656,15 +616,14 @@ public class Dna protein.toString()); if (rf != 0) { - if (jalview.bin.Cache.log != null) + final String errMsg = "trimming contigs for incomplete terminal codon."; + if (Cache.log != null) { - jalview.bin.Cache.log - .debug("trimming contigs for incomplete terminal codon."); + Cache.log.debug(errMsg); } else { - System.err - .println("trimming contigs for incomplete terminal codon."); + System.err.println(errMsg); } // map and trim contigs to ORF region vc = scontigs.length - 1; @@ -694,7 +653,9 @@ public class Dna scontigs = t; } if (vc <= 0) + { scontigs = null; + } } if (scontigs != null) { @@ -705,7 +666,9 @@ public class Dna scontigs[vc] = selection.findPosition(scontigs[vc]); // not from 1! scontigs[vc + 1] = selection.findPosition(scontigs[vc + 1]); // exclusive if (scontigs[vc + 1] == selection.getEnd()) + { break; + } } // trim trailing empty intervals. if ((vc + 2) < scontigs.length) @@ -731,27 +694,19 @@ public class Dna MapList map = new MapList(scontigs, new int[] { 1, resSize }, 3, 1); - // update newseq as if it was generated as mapping from product - - if (product != null) - { - newseq.setName(product.getSource() + "|" - + product.getAccessionId()); - if (product.getMap() != null) - { - // Mapping mp = product.getMap(); - // newseq.setStart(mp.getPosition(scontigs[0])); - // newseq.setEnd(mp - // .getPosition(scontigs[scontigs.length - 1])); - } - } transferCodedFeatures(selection, newseq, map, null, null); - SequenceI rseq = newseq.deriveSequence(); // construct a dataset - // sequence for our new - // peptide, regardless. - // store a mapping (this actually stores a mapping between the dataset - // sequences for the two sequences - codons.addMap(selection, rseq, map); + + /* + * Construct a dataset sequence for our new peptide. + */ + SequenceI rseq = newseq.deriveSequence(); + + /* + * Store a mapping (between the dataset sequences for the two + * sequences). + */ + // SIDE-EFFECT: acf stores the aligned sequence reseq; to remove! + acf.addMap(selection, rseq, map); return rseq; } } @@ -761,6 +716,53 @@ public class Dna } /** + * Insert a gap into the aligned proteins and the codon mapping array. + * + * @param pos + * @param proteinSeqs + * @return + */ + protected void insertAAGap(int pos, + List proteinSeqs) + { + aaWidth++; + for (SequenceI seq : proteinSeqs) + { + seq.insertCharAt(pos, gapChar); + } + + checkCodonFrameWidth(); + if (pos < aaWidth) + { + aaWidth++; + + /* + * Shift from [pos] to the end one to the right, and null out [pos] + */ + System.arraycopy(alignedCodons, pos, alignedCodons, pos + 1, + alignedCodons.length - pos - 1); + alignedCodons[pos] = null; + } + } + + /** + * Check the codons array can accommodate a single insertion, if not resize + * it. + */ + protected void checkCodonFrameWidth() + { + if (alignedCodons[alignedCodons.length - 1] != null) + { + /* + * arraycopy insertion would bump a filled slot off the end, so expand. + */ + AlignedCodon[] c = new AlignedCodon[alignedCodons.length + 10]; + System.arraycopy(alignedCodons, 0, c, 0, alignedCodons.length); + alignedCodons = c; + } + } + + /** * Given a peptide newly translated from a dna sequence, copy over and set any * features on the peptide from the DNA. If featureTypes is null, all features * on the dna sequence are searched (rather than just the displayed ones), and @@ -770,20 +772,19 @@ public class Dna * @param pep * @param map * @param featureTypes - * hash who's keys are the displayed feature type strings + * hash whose keys are the displayed feature type strings * @param featureGroups * hash where keys are feature groups and values are Boolean objects * indicating if they are displayed. */ private static void transferCodedFeatures(SequenceI dna, SequenceI pep, - MapList map, Hashtable featureTypes, Hashtable featureGroups) + MapList map, Map featureTypes, + Map featureGroups) { - SequenceFeature[] sf = (dna.getDatasetSequence() != null ? dna - .getDatasetSequence() : dna).getSequenceFeatures(); + SequenceFeature[] sfs = dna.getSequenceFeatures(); Boolean fgstate; - jalview.datamodel.DBRefEntry[] dnarefs = jalview.util.DBRefUtils - .selectRefs(dna.getDBRef(), - jalview.datamodel.DBRefSource.DNACODINGDBS); + DBRefEntry[] dnarefs = DBRefUtils.selectRefs(dna.getDBRef(), + DBRefSource.DNACODINGDBS); if (dnarefs != null) { // intersect with pep @@ -795,16 +796,16 @@ public class Dna } } } - if (sf != null) + if (sfs != null) { - for (int f = 0; f < sf.length; f++) + for (SequenceFeature sf : sfs) { - fgstate = (featureGroups == null) ? null : ((Boolean) featureGroups - .get(sf[f].featureGroup)); - if ((featureTypes == null || featureTypes.containsKey(sf[f] - .getType())) && (fgstate == null || fgstate.booleanValue())) + fgstate = (featureGroups == null) ? null : featureGroups + .get(sf.featureGroup); + if ((featureTypes == null || featureTypes.containsKey(sf.getType())) + && (fgstate == null || fgstate.booleanValue())) { - if (FeatureProperties.isCodingFeature(null, sf[f].getType())) + if (FeatureProperties.isCodingFeature(null, sf.getType())) { // if (map.intersectsFrom(sf[f].begin, sf[f].end)) { diff --git a/src/jalview/analysis/SequenceIdMatcher.java b/src/jalview/analysis/SequenceIdMatcher.java index c3d7ac1..e6a4853 100755 --- a/src/jalview/analysis/SequenceIdMatcher.java +++ b/src/jalview/analysis/SequenceIdMatcher.java @@ -20,9 +20,12 @@ */ package jalview.analysis; -import java.util.*; +import jalview.datamodel.DBRefEntry; +import jalview.datamodel.SequenceI; -import jalview.datamodel.*; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.Vector; /** * Routines for approximate Sequence Id resolution by name using string @@ -258,14 +261,20 @@ public class SequenceIdMatcher } } + @Override public int hashCode() { return ((id.length() >= 4) ? id.substring(0, 4).hashCode() : id .hashCode()); } + @Override public boolean equals(Object s) { + if (s == null) + { + return false; + } if (s instanceof SeqIdName) { return this.equals((SeqIdName) s); diff --git a/src/jalview/analysis/StructureFrequency.java b/src/jalview/analysis/StructureFrequency.java index 65dd84a..3c8274e 100644 --- a/src/jalview/analysis/StructureFrequency.java +++ b/src/jalview/analysis/StructureFrequency.java @@ -20,10 +20,14 @@ */ package jalview.analysis; -import java.util.*; - +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.Annotation; +import jalview.datamodel.SequenceFeature; +import jalview.datamodel.SequenceI; import jalview.util.Format; -import jalview.datamodel.*; + +import java.util.ArrayList; +import java.util.Hashtable; /** * Takes in a vector or array of sequences and column start and column end and @@ -36,6 +40,8 @@ import jalview.datamodel.*; */ public class StructureFrequency { + public static final int STRUCTURE_PROFILE_LENGTH = 74; + // No need to store 1000s of strings which are not // visible to the user. public static final String MAXCOUNT = "C"; @@ -187,6 +193,7 @@ public class StructureFrequency // UPDATE this for new values if (profile) { + // TODO 1-dim array with jsize in [0], nongapped in [1]; or Pojo residueHash.put(PROFILE, new int[][] { values, new int[] { jSize, (jSize - values['-']) } }); @@ -413,7 +420,7 @@ public class StructureFrequency * ((c == 0) ? "" : "; ") + alphabet[c] + " " + ((int) tval) + "%"; } } * else { */ - Object[] ca = new Object[625]; + int[][] ca = new int[625][]; float[] vl = new float[625]; int x = 0; for (int c = 65; c < 90; c++) @@ -429,14 +436,18 @@ public class StructureFrequency jalview.util.QuickSort.sort(vl, ca); int p = 0; + /* + * profile[1] is {total, ungappedTotal} + */ + final int divisor = profile[1][ignoreGapsInConsensusCalculation ? 1 + : 0]; for (int c = 624; c > 0; c--) { if (vl[c] > 0) { - tval = (vl[c] * 100f / profile[1][ignoreGapsInConsensusCalculation ? 1 - : 0]); - mouseOver += ((p == 0) ? "" : "; ") + (char) ((int[]) ca[c])[0] - + (char) ((int[]) ca[c])[1] + " " + fmt.form(tval) + tval = (vl[c] * 100f / divisor); + mouseOver += ((p == 0) ? "" : "; ") + (char) ca[c][0] + + (char) ca[c][1] + " " + fmt.form(tval) + "%"; p++; @@ -463,16 +474,19 @@ public class StructureFrequency public static int[] extractProfile(Hashtable hconsensus, boolean ignoreGapsInConsensusCalculation) { - int[] rtnval = new int[74]; // 2*(5*5)+2 + int[] rtnval = new int[STRUCTURE_PROFILE_LENGTH]; // 2*(5*5)+2 int[][] profile = (int[][]) hconsensus.get(StructureFrequency.PROFILE); int[][] pairs = (int[][]) hconsensus .get(StructureFrequency.PAIRPROFILE); if (profile == null) + { return null; + } // TODO fix the object length, also do it in completeConsensus - Object[] ca = new Object[625]; + // Object[] ca = new Object[625]; + int[][] ca = new int[625][]; float[] vl = new float[625]; int x = 0; for (int c = 65; c < 90; c++) @@ -487,21 +501,28 @@ public class StructureFrequency } jalview.util.QuickSort.sort(vl, ca); - rtnval[0] = 2; + int valuesCount = 0; rtnval[1] = 0; + int offset = 2; + final int divisor = profile[1][ignoreGapsInConsensusCalculation ? 1 : 0]; for (int c = 624; c > 0; c--) { if (vl[c] > 0) { - rtnval[rtnval[0]++] = ((int[]) ca[c])[0]; - rtnval[rtnval[0]++] = ((int[]) ca[c])[1]; - rtnval[rtnval[0]] = (int) (vl[c] * 100f / profile[1][ignoreGapsInConsensusCalculation ? 1 - : 0]); - rtnval[1] += rtnval[rtnval[0]++]; + rtnval[offset++] = ca[c][0]; + rtnval[offset++] = ca[c][1]; + rtnval[offset] = (int) (vl[c] * 100f / divisor); + rtnval[1] += rtnval[offset++]; + valuesCount++; } } + rtnval[0] = valuesCount; - return rtnval; + // insert profile type code in position 0 + int[] result = new int[rtnval.length + 1]; + result[0] = AlignmentAnnotation.STRUCTURE_PROFILE; + System.arraycopy(rtnval, 0, result, 1, rtnval.length); + return result; } public static void main(String args[]) diff --git a/src/jalview/api/AlignViewportI.java b/src/jalview/api/AlignViewportI.java index 6faa133..c49ee39 100644 --- a/src/jalview/api/AlignViewportI.java +++ b/src/jalview/api/AlignViewportI.java @@ -40,7 +40,7 @@ import java.util.Map; * @author jimp * */ -public interface AlignViewportI +public interface AlignViewportI extends ViewStyleI { int getCharWidth(); @@ -75,11 +75,16 @@ public interface AlignViewportI Hashtable[] getSequenceConsensusHash(); - Hashtable[] getRnaStructureConsensusHash(); + /** + * Get consensus data table for the cDNA complement of this alignment (if any) + * + * @return + */ + Hashtable[] getComplementConsensusHash(); - boolean getIgnoreGapsConsensus(); + Hashtable[] getRnaStructureConsensusHash(); - boolean getCentreColumnLabels(); + boolean isIgnoreGapsConsensus(); boolean isCalculationInProgress(AlignmentAnnotation alignmentAnnotation); @@ -95,6 +100,13 @@ public interface AlignViewportI AlignmentAnnotation getAlignmentConsensusAnnotation(); /** + * get the container for cDNA complement consensus annotation + * + * @return + */ + AlignmentAnnotation getComplementConsensusAnnotation(); + + /** * Test to see if viewport is still open and active * * @return true indicates that all references to viewport should be dropped @@ -122,6 +134,13 @@ public interface AlignViewportI void setSequenceConsensusHash(Hashtable[] hconsensus); /** + * Set the cDNA complement consensus for the viewport + * + * @param hconsensus + */ + void setComplementConsensusHash(Hashtable[] hconsensus); + + /** * * @return the alignment annotatino row for the structure consensus * calculation @@ -320,10 +339,9 @@ public interface AlignViewportI * first column (inclusive, from 0) * @param max * last column (exclusive) - * @return int[][] range of {start,end} visible positions TODO: change to list - * of int ranges + * @return int[][] range of {start,end} visible positions */ - int[][] getVisibleRegionBoundaries(int min, int max); + List getVisibleRegionBoundaries(int min, int max); /** * This method returns an array of new SequenceI objects derived from the @@ -354,4 +372,45 @@ public interface AlignViewportI boolean hasHiddenRows(); + /** + * + * @return a copy of this view's current display settings + */ + public ViewStyleI getViewStyle(); + + /** + * update the view's display settings with the given style set + * + * @param settingsForView + */ + public void setViewStyle(ViewStyleI settingsForView); + + /** + * Returns a viewport which holds the cDna for this (protein), or vice versa, + * or null if none is set. + * + * @return + */ + AlignViewportI getCodingComplement(); + + /** + * Sets the viewport which holds the cDna for this (protein), or vice versa. + * Implementation should guarantee that the reciprocal relationship is always + * set, i.e. each viewport is the complement of the other. + */ + void setCodingComplement(AlignViewportI sl); + + /** + * Answers true if viewport hosts DNA/RNA, else false. + * + * @return + */ + boolean isNucleotide(); + + /** + * Returns an id guaranteed to be unique for this viewport. + * + * @return + */ + String getViewId(); } diff --git a/src/jalview/api/AlignmentViewPanel.java b/src/jalview/api/AlignmentViewPanel.java index 09ccbb4..f0fd2e1 100644 --- a/src/jalview/api/AlignmentViewPanel.java +++ b/src/jalview/api/AlignmentViewPanel.java @@ -32,6 +32,8 @@ import jalview.structure.StructureSelectionManager; public interface AlignmentViewPanel extends OOMHandlerI { + AlignViewportI getAlignViewport(); + AlignmentI getAlignment(); StructureSelectionManager getStructureSelectionManager(); diff --git a/src/jalview/api/SplitContainerI.java b/src/jalview/api/SplitContainerI.java new file mode 100644 index 0000000..b9c3121 --- /dev/null +++ b/src/jalview/api/SplitContainerI.java @@ -0,0 +1,38 @@ +package jalview.api; + +import jalview.datamodel.AlignmentI; + +/** + * Describes a visual container that can show two alignments. + * + * @author gmcarstairs + * + */ +public interface SplitContainerI +{ + + /** + * Set visibility of the specified split view component. + * + * @param alignFrame + * @param show + */ + // TODO need an interface for AlignFrame? + void setComplementVisible(Object alignFrame, boolean show); + + /** + * Returns the alignment that is complementary to the one in the given + * AlignFrame, or null. + */ + AlignmentI getComplement(Object af); + + /** + * Returns the frame title for the alignment that is complementary to the one + * in the given AlignFrame, or null. + * + * @param af + * @return + */ + String getComplementTitle(Object af); + +} diff --git a/src/jalview/api/ViewStyleI.java b/src/jalview/api/ViewStyleI.java new file mode 100644 index 0000000..8fa7f8f --- /dev/null +++ b/src/jalview/api/ViewStyleI.java @@ -0,0 +1,202 @@ +package jalview.api; + +import java.awt.Color; + +public interface ViewStyleI +{ + + void setColourAppliesToAllGroups(boolean b); + + boolean getColourAppliesToAllGroups(); + + boolean getAbovePIDThreshold(); + + void setIncrement(int inc); + + int getIncrement(); + + boolean getConservationSelected(); + + void setConservationSelected(boolean b); + + void setShowHiddenMarkers(boolean show); + + boolean getShowHiddenMarkers(); + + void setScaleRightWrapped(boolean b); + + void setScaleLeftWrapped(boolean b); + + void setScaleAboveWrapped(boolean b); + + boolean getScaleLeftWrapped(); + + boolean getScaleAboveWrapped(); + + boolean getScaleRightWrapped(); + + void setAbovePIDThreshold(boolean b); + + void setThreshold(int thresh); + + int getThreshold(); + + boolean getShowJVSuffix(); + + void setShowJVSuffix(boolean b); + + void setWrapAlignment(boolean state); + + void setShowText(boolean state); + + void setRenderGaps(boolean state); + + boolean getColourText(); + + void setColourText(boolean state); + + void setShowBoxes(boolean state); + + boolean getWrapAlignment(); + + boolean getShowText(); + + int getWrappedWidth(); + + void setWrappedWidth(int w); + + int getCharHeight(); + + void setCharHeight(int h); + + int getCharWidth(); + + void setCharWidth(int w); + + boolean getShowBoxes(); + + boolean getShowUnconserved(); + + void setShowUnconserved(boolean showunconserved); + + boolean isDisplayReferenceSeq(); + + void setDisplayReferenceSeq(boolean displayReferenceSeq); + + boolean isColourByReferenceSeq(); + + void setSeqNameItalics(boolean default1); + + void setShowSequenceFeatures(boolean b); + + boolean isShowSequenceFeatures(); + + boolean isRightAlignIds(); + + void setRightAlignIds(boolean rightAlignIds); + + boolean isShowAnnotation(); + + void setShowAnnotation(boolean b); + + void setShowSeqFeaturesHeight(boolean selected); + + boolean isShowSequenceFeaturesHeight(); + + void setColourByReferenceSeq(boolean colourByReferenceSeq); + + Color getTextColour(); + + Color getTextColour2(); + + int getThresholdTextColour(); + + boolean isConservationColourSelected(); + + boolean isRenderGaps(); + + boolean isShowColourText(); + + boolean isShowSeqFeaturesHeight(); + + void setConservationColourSelected(boolean conservationColourSelected); + + void setShowColourText(boolean showColourText); + + void setTextColour(Color textColour); + + void setThresholdTextColour(int thresholdTextColour); + + void setTextColour2(Color textColour2); + + boolean isSeqNameItalics(); + + void setUpperCasebold(boolean upperCasebold); + + boolean isUpperCasebold(); + + boolean sameStyle(ViewStyleI them); + + void setFontName(String name); + + void setFontStyle(int style); + + void setFontSize(int size); + + int getFontStyle(); + + String getFontName(); + + int getFontSize(); + + /** + * @return width of Sequence and Annotation ID margin. If less than zero, then + * width will be autocalculated + */ + int getIdWidth(); + + /** + * Set width if + * + * @param i + */ + + void setIdWidth(int i); + + /** + * centre columnar annotation labels in displayed alignment annotation + */ + boolean isCentreColumnLabels(); + + /** + * centre columnar annotation labels in displayed alignment annotation + */ + void setCentreColumnLabels(boolean centreColumnLabels); + + /** + * enable or disable the display of Database Cross References in the sequence + * ID tooltip + */ + void setShowDBRefs(boolean showdbrefs); + + /** + * + * @return true if Database References are to be displayed on tooltips. + */ + boolean isShowDBRefs(); + + /** + * + * @return true if Non-positional features are to be displayed on tooltips. + */ + boolean isShowNPFeats(); + + /** + * enable or disable the display of Non-Positional sequence features in the + * sequence ID tooltip + * + * @param show + */ + void setShowNPFeats(boolean shownpfeats); + +} diff --git a/src/jalview/appletgui/APopupMenu.java b/src/jalview/appletgui/APopupMenu.java index 1059863..d71fdd4 100644 --- a/src/jalview/appletgui/APopupMenu.java +++ b/src/jalview/appletgui/APopupMenu.java @@ -20,14 +20,33 @@ */ package jalview.appletgui; +import java.awt.CheckboxMenuItem; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.Vector; + import jalview.analysis.AAFrequency; +import jalview.analysis.AlignmentAnnotationUtils; +import jalview.analysis.AlignmentUtils; import jalview.analysis.Conservation; import jalview.commands.ChangeCaseCommand; import jalview.commands.EditCommand; import jalview.commands.EditCommand.Action; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; import jalview.datamodel.DBRefEntry; import jalview.datamodel.PDBEntry; -import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; @@ -48,19 +67,11 @@ import jalview.schemes.ZappoColourScheme; import jalview.util.MessageManager; import jalview.util.UrlLink; -import java.awt.CheckboxMenuItem; -import java.awt.Frame; -import java.awt.Menu; -import java.awt.MenuItem; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.util.Vector; - public class APopupMenu extends java.awt.PopupMenu implements ActionListener, ItemListener { + private static final String ALL_ANNOTATIONS = "All"; + Menu groupMenu = new Menu(); MenuItem editGroupName = new MenuItem(); @@ -111,12 +122,29 @@ public class APopupMenu extends java.awt.PopupMenu implements CheckboxMenuItem displayNonconserved = new CheckboxMenuItem(); + Menu seqShowAnnotationsMenu = new Menu( + MessageManager.getString("label.show_annotations")); + + Menu seqHideAnnotationsMenu = new Menu( + MessageManager.getString("label.hide_annotations")); + + MenuItem seqAddReferenceAnnotations = new MenuItem( + MessageManager.getString("label.add_reference_annotations")); + + Menu groupShowAnnotationsMenu = new Menu( + MessageManager.getString("label.show_annotations")); + + Menu groupHideAnnotationsMenu = new Menu( + MessageManager.getString("label.hide_annotations")); + + MenuItem groupAddReferenceAnnotations = new MenuItem( + MessageManager.getString("label.add_reference_annotations")); + Menu editMenu = new Menu(MessageManager.getString("action.edit")); - MenuItem copy = new MenuItem( - MessageManager.getString("label.jalview_copy")); + MenuItem copy = new MenuItem(MessageManager.getString("action.copy")); - MenuItem cut = new MenuItem(MessageManager.getString("label.jalview_cut")); + MenuItem cut = new MenuItem(MessageManager.getString("action.cut")); MenuItem toUpper = new MenuItem( MessageManager.getString("label.to_upper_case")); @@ -154,7 +182,7 @@ public class APopupMenu extends java.awt.PopupMenu implements MenuItem makeReferenceSeq = new MenuItem(); - Sequence seq; + SequenceI seq; MenuItem revealAll = new MenuItem(); @@ -167,7 +195,8 @@ public class APopupMenu extends java.awt.PopupMenu implements Menu menu1 = new Menu(); - public APopupMenu(AlignmentPanel apanel, final Sequence seq, Vector links) + public APopupMenu(AlignmentPanel apanel, final SequenceI seq, + Vector links) { // ///////////////////////////////////////////////////////// // If this is activated from the sequence panel, the user may want to @@ -196,12 +225,13 @@ public class APopupMenu extends java.awt.PopupMenu implements outputmenu.add(item); } - SequenceGroup sg = ap.av.getSelectionGroup(); + buildAnnotationSubmenus(); + SequenceGroup sg = ap.av.getSelectionGroup(); if (sg != null && sg.getSize() > 0) { editGroupName.setLabel(MessageManager.formatMessage( - "label.name_param", new String[] + "label.name_param", new Object[] { sg.getName() })); showText.setState(sg.getDisplayText()); showColourText.setState(sg.getColourText()); @@ -228,10 +258,9 @@ public class APopupMenu extends java.awt.PopupMenu implements if (links != null && links.size() > 0) { Menu linkMenu = new Menu(MessageManager.getString("action.link")); - String link; for (int i = 0; i < links.size(); i++) { - link = links.elementAt(i).toString(); + String link = links.elementAt(i); UrlLink urlLink = new UrlLink(link); if (!urlLink.isValid()) { @@ -361,7 +390,7 @@ public class APopupMenu extends java.awt.PopupMenu implements .getString("action.set_as_reference")); // ); } repGroup.setLabel(MessageManager.formatMessage( - "label.represent_group_with", new String[] + "label.represent_group_with", new Object[] { seq.getName() })); } else @@ -391,6 +420,95 @@ public class APopupMenu extends java.awt.PopupMenu implements } /** + * Build menus for annotation types that may be shown or hidden, and for + * 'reference annotations' that may be added to the alignment. + */ + private void buildAnnotationSubmenus() + { + /* + * First for the currently selected sequence (if there is one): + */ + final List selectedSequence = (seq == null ? Collections + . emptyList() : Arrays.asList(seq)); + buildAnnotationTypesMenus(seqShowAnnotationsMenu, + seqHideAnnotationsMenu, selectedSequence); + configureReferenceAnnotationsMenu(seqAddReferenceAnnotations, + selectedSequence); + + /* + * and repeat for the current selection group (if there is one): + */ + final List selectedGroup = (ap.av.getSelectionGroup() == null ? Collections + . emptyList() : ap.av.getSelectionGroup() + .getSequences()); + buildAnnotationTypesMenus(groupShowAnnotationsMenu, + groupHideAnnotationsMenu, selectedGroup); + configureReferenceAnnotationsMenu(groupAddReferenceAnnotations, + selectedGroup); + } + + /** + * Determine whether or not to enable 'add reference annotations' menu item. + * It is enable if there are any annotations, on any of the selected + * sequences, which are not yet on the alignment (visible or not). + * + * @param menu + * @param forSequences + */ + private void configureReferenceAnnotationsMenu(MenuItem menuItem, + List forSequences) + { + menuItem.setEnabled(false); + + /* + * Temporary store to hold distinct calcId / type pairs for the tooltip. + * Using TreeMap means calcIds are shown in alphabetical order. + */ + Map tipEntries = new TreeMap(); + final Map> candidates = new LinkedHashMap>(); + AlignmentI al = this.ap.av.getAlignment(); + AlignmentUtils.findAddableReferenceAnnotations(forSequences, + tipEntries, candidates, al); + if (!candidates.isEmpty()) + { + StringBuilder tooltip = new StringBuilder(64); + tooltip.append(MessageManager.getString("label.add_annotations_for")); + + /* + * Found annotations that could be added. Enable the menu item, and + * configure its action. + */ + menuItem.setEnabled(true); + + menuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + addReferenceAnnotations_actionPerformed(candidates); + } + }); + } + } + + /** + * Add annotations to the sequences and to the alignment. + * + * @param candidates + * a map whose keys are sequences on the alignment, and values a list + * of annotations to add to each sequence + */ + protected void addReferenceAnnotations_actionPerformed( + Map> candidates) + { + final SequenceGroup selectionGroup = this.ap.av.getSelectionGroup(); + final AlignmentI alignment = this.ap.getAlignment(); + AlignmentUtils.addReferenceAnnotations(candidates, alignment, + selectionGroup); + refresh(); + } + + /** * add a show URL menu item to the given linkMenu * * @param linkMenu @@ -591,7 +709,7 @@ public class APopupMenu extends java.awt.PopupMenu implements { if (seq == null) { - seq = (Sequence) sg.getSequenceAt(0); + seq = sg.getSequenceAt(0); } EditNameDialog dialog = new EditNameDialog(seq.getSequenceAsString( @@ -619,10 +737,9 @@ public class APopupMenu extends java.awt.PopupMenu implements else if (source == toUpper || source == toLower || source == toggleCase) { SequenceGroup sg = ap.av.getSelectionGroup(); - Vector regions = new Vector(); if (sg != null) { - int[][] startEnd = ap.av.getVisibleRegionBoundaries( + List startEnd = ap.av.getVisibleRegionBoundaries( sg.getStartRes(), sg.getEndRes() + 1); String description; @@ -708,15 +825,14 @@ public class APopupMenu extends java.awt.PopupMenu implements Frame frame = new Frame(); frame.add(cap); jalview.bin.JalviewLite.addFrame(frame, MessageManager.formatMessage( - "label.selection_output_command", new String[] + "label.selection_output_command", new Object[] { e.getActionCommand() }), 600, 500); // JBPNote: getSelectionAsNewSequence behaviour has changed - this method // now returns a full copy of sequence data // TODO consider using getSequenceSelection instead here cap.setText(new jalview.io.AppletFormatAdapter().formatSequences( - e.getActionCommand(), - ap.av.showJVSuffix, ap.av, true)); + e.getActionCommand(), ap.av.getShowJVSuffix(), ap.av, true)); } @@ -740,7 +856,7 @@ public class APopupMenu extends java.awt.PopupMenu implements for (SequenceI seq : sequences) { contents.append(MessageManager.formatMessage( - "label.annotation_for_displayid", new String[] + "label.annotation_for_displayid", new Object[] { seq.getDisplayId(true) })); new SequenceAnnotationReport(null) .createSequenceAnnotationReport( @@ -759,7 +875,7 @@ public class APopupMenu extends java.awt.PopupMenu implements + (sequences.length == 1 ? sequences[0].getDisplayId(true) : "Selection"), 600, 500); cap.setText(MessageManager.formatMessage("label.html_content", - new String[] + new Object[] { contents.toString() })); } @@ -786,12 +902,12 @@ public class APopupMenu extends java.awt.PopupMenu implements if (ap.av.applet.jmolAvailable) { - new jalview.appletgui.AppletJmol(entry, new Sequence[] + new jalview.appletgui.AppletJmol(entry, new SequenceI[] { seq }, null, ap, AppletFormatAdapter.URL); } else { - new MCview.AppletPDBViewer(entry, new Sequence[] + new MCview.AppletPDBViewer(entry, new SequenceI[] { seq }, null, ap, AppletFormatAdapter.URL); } @@ -804,7 +920,7 @@ public class APopupMenu extends java.awt.PopupMenu implements Frame frame = new Frame(); frame.add(cap); jalview.bin.JalviewLite.addFrame(frame, MessageManager.formatMessage( - "label.paste_pdb_file_for_sequence", new String[] + "label.paste_pdb_file_for_sequence", new Object[] { seq.getName() }), 400, 300); } } @@ -848,7 +964,7 @@ public class APopupMenu extends java.awt.PopupMenu implements pdb.setLabel(MessageManager.getString("label.view_pdb_structure")); hideSeqs.setLabel(MessageManager.getString("action.hide_sequences")); repGroup.setLabel(MessageManager.formatMessage( - "label.represent_group_with", new String[] + "label.represent_group_with", new Object[] { "" })); revealAll.setLabel(MessageManager.getString("action.reveal_all")); revealSeq.setLabel(MessageManager.getString("action.reveal_sequences")); @@ -859,6 +975,9 @@ public class APopupMenu extends java.awt.PopupMenu implements this.add(revealSeq); this.add(revealAll); // groupMenu.add(selSeqDetails); + groupMenu.add(groupShowAnnotationsMenu); + groupMenu.add(groupHideAnnotationsMenu); + groupMenu.add(groupAddReferenceAnnotations); groupMenu.add(editMenu); groupMenu.add(outputmenu); groupMenu.add(sequenceFeature); @@ -925,6 +1044,9 @@ public class APopupMenu extends java.awt.PopupMenu implements editMenu.add(toLower); toLower.addActionListener(this); editMenu.add(toggleCase); + seqMenu.add(seqShowAnnotationsMenu); + seqMenu.add(seqHideAnnotationsMenu); + seqMenu.add(seqAddReferenceAnnotations); seqMenu.add(sequenceName); seqMenu.add(makeReferenceSeq); // seqMenu.add(sequenceDetails); @@ -1024,7 +1146,7 @@ public class APopupMenu extends java.awt.PopupMenu implements int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs, getGroup() .getName()); - sg.cs.setThreshold(threshold, ap.av.getIgnoreGapsConsensus()); + sg.cs.setThreshold(threshold, ap.av.isIgnoreGapsConsensus()); SliderPanel.showPIDSlider(); @@ -1032,7 +1154,7 @@ public class APopupMenu extends java.awt.PopupMenu implements else // remove PIDColouring { - sg.cs.setThreshold(0, ap.av.getIgnoreGapsConsensus()); + sg.cs.setThreshold(0, ap.av.isIgnoreGapsConsensus()); } refresh(); @@ -1205,4 +1327,109 @@ public class APopupMenu extends java.awt.PopupMenu implements ap.av.sendSelection(); } + /** + * Add annotation types to 'Show annotations' and/or 'Hide annotations' menus. + * "All" is added first, followed by a separator. Then add any annotation + * types associated with the current selection. Separate menus are built for + * the selected sequence group (if any), and the selected sequence. + *

+ * Some annotation rows are always rendered together - these can be identified + * by a common graphGroup property > -1. Only one of each group will be marked + * as visible (to avoid duplication of the display). For such groups we add a + * composite type name, e.g. + *

+ * IUPredWS (Long), IUPredWS (Short) + * + * @param seq + */ + protected void buildAnnotationTypesMenus(Menu showMenu, Menu hideMenu, + List forSequences) + { + showMenu.removeAll(); + hideMenu.removeAll(); + + final List all = Arrays.asList(ALL_ANNOTATIONS); + addAnnotationTypeToShowHide(showMenu, forSequences, "", all, true, true); + addAnnotationTypeToShowHide(hideMenu, forSequences, "", all, true, + false); + showMenu.addSeparator(); + hideMenu.addSeparator(); + + final AlignmentAnnotation[] annotations = ap.getAlignment() + .getAlignmentAnnotation(); + + /* + * Find shown/hidden annotations types, distinguished by source (calcId), + * and grouped by graphGroup. Using LinkedHashMap means we will retrieve in + * the insertion order, which is the order of the annotations on the + * alignment. + */ + Map>> shownTypes = new LinkedHashMap>>(); + Map>> hiddenTypes = new LinkedHashMap>>(); + AlignmentAnnotationUtils.getShownHiddenTypes(shownTypes, + hiddenTypes, + AlignmentAnnotationUtils.asList(annotations), + forSequences); + + for (String calcId : hiddenTypes.keySet()) + { + for (List type : hiddenTypes.get(calcId)) + { + addAnnotationTypeToShowHide(showMenu, forSequences, + calcId, type, false, true); + } + } + // grey out 'show annotations' if none are hidden + showMenu.setEnabled(!hiddenTypes.isEmpty()); + + for (String calcId : shownTypes.keySet()) + { + for (List type : shownTypes.get(calcId)) + { + addAnnotationTypeToShowHide(hideMenu, forSequences, + calcId, type, false, false); + } + } + // grey out 'hide annotations' if none are shown + hideMenu.setEnabled(!shownTypes.isEmpty()); + } + + /** + * Add one annotation type to the 'Show Annotations' or 'Hide Annotations' + * menus. + * + * @param showOrHideMenu + * the menu to add to + * @param forSequences + * the sequences whose annotations may be shown or hidden + * @param calcId + * @param types + * the label to add + * @param allTypes + * if true this is a special label meaning 'All' + * @param actionIsShow + * if true, the select menu item action is to show the annotation + * type, else hide + */ + protected void addAnnotationTypeToShowHide(Menu showOrHideMenu, + final List forSequences, String calcId, + final List types, final boolean allTypes, + final boolean actionIsShow) + { + String label = types.toString(); // [a, b, c] + label = label.substring(1, label.length() - 1); + final MenuItem item = new MenuItem(label); + item.addActionListener(new java.awt.event.ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + AlignmentUtils.showOrHideSequenceAnnotations(ap.getAlignment(), types, + forSequences, allTypes, actionIsShow); + refresh(); + } + }); + showOrHideMenu.add(item); + } + } diff --git a/src/jalview/appletgui/AlignFrame.java b/src/jalview/appletgui/AlignFrame.java index 623388b..3e919f6 100644 --- a/src/jalview/appletgui/AlignFrame.java +++ b/src/jalview/appletgui/AlignFrame.java @@ -20,9 +20,45 @@ */ package jalview.appletgui; +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.CheckboxMenuItem; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Label; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.IOException; +import java.net.URL; +import java.net.URLEncoder; +import java.util.Arrays; +import java.util.Deque; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.Vector; + import jalview.analysis.AlignmentSorter; +import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; import jalview.api.AlignViewControllerGuiI; import jalview.api.AlignViewControllerI; +import jalview.api.AlignViewportI; import jalview.api.FeatureRenderer; import jalview.api.SequenceStructureBinding; import jalview.bin.JalviewLite; @@ -35,6 +71,7 @@ import jalview.commands.RemoveGapsCommand; import jalview.commands.SlideSequencesCommand; import jalview.commands.TrimRegionCommand; import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.AlignmentOrder; import jalview.datamodel.ColumnSelection; @@ -64,40 +101,9 @@ import jalview.schemes.TurnColourScheme; import jalview.schemes.ZappoColourScheme; import jalview.structure.StructureSelectionManager; import jalview.structures.models.AAStructureBindingModel; +import jalview.util.MappingUtils; import jalview.util.MessageManager; -import java.awt.BorderLayout; -import java.awt.Canvas; -import java.awt.CheckboxMenuItem; -import java.awt.Color; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Frame; -import java.awt.Graphics; -import java.awt.Label; -import java.awt.Menu; -import java.awt.MenuBar; -import java.awt.MenuItem; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.io.IOException; -import java.net.URL; -import java.net.URLEncoder; -import java.util.Arrays; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; -import java.util.Vector; - public class AlignFrame extends EmbmenuFrame implements ActionListener, ItemListener, KeyListener, AlignViewControllerGuiI { @@ -113,9 +119,41 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, String jalviewServletURL; - public AlignFrame(AlignmentI al, jalview.bin.JalviewLite applet, + /* + * Flag for showing autocalculated consensus above or below other consensus + * rows + */ + private boolean showAutoCalculatedAbove; + + private SequenceAnnotationOrder annotationSortOrder; + + /** + * Constructor that creates the frame and adds it to the display. + * + * @param al + * @param applet + * @param title + * @param embedded + */ + public AlignFrame(AlignmentI al, JalviewLite applet, String title, boolean embedded) { + this(al, applet, title, embedded, true); + } + + /** + * Constructor that optionally allows the frame to be displayed or only + * created. + * + * @param al + * @param applet + * @param title + * @param embedded + * @param addToDisplay + */ + public AlignFrame(AlignmentI al, JalviewLite applet, + String title, boolean embedded, boolean addToDisplay) + { if (applet != null) { jalviewServletURL = applet.getParameter("APPLICATION_URL"); @@ -157,7 +195,6 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, viewport.updateConservation(alignPanel); viewport.updateConsensus(alignPanel); - annotationPanelMenuItem.setState(viewport.showAnnotation); displayNonconservedMenuItem.setState(viewport.getShowUnconserved()); followMouseOverFlag.setState(viewport.getFollowHighlight()); showGroupConsensus.setState(viewport.isShowGroupConsensus()); @@ -166,8 +203,10 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, showSequenceLogo.setState(viewport.isShowSequenceLogo()); normSequenceLogo.setState(viewport.isNormaliseSequenceLogo()); applyToAllGroups.setState(viewport.getColourAppliesToAllGroups()); + showAlignmentAnnotations.setState(viewport.isShowAnnotation()); + showSequenceAnnotations.setState(viewport.isShowAnnotation()); - seqLimits.setState(viewport.showJVSuffix); + seqLimits.setState(viewport.getShowJVSuffix()); if (applet != null) { @@ -233,8 +272,19 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, alignPanel.annotationPanelHolder.addKeyListener(this); alignPanel.annotationSpaceFillerHolder.addKeyListener(this); alignPanel.alabels.addKeyListener(this); - createAlignFrameWindow(embedded, title); + if (addToDisplay) + { + addToDisplay(embedded); + } + } + + /** + * @param embedded + */ + public void addToDisplay(boolean embedded) + { + createAlignFrameWindow(embedded); validate(); alignPanel.adjustAnnotationHeight(); alignPanel.paintAlignment(true); @@ -498,7 +548,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, } case KeyEvent.VK_PAGE_UP: - if (viewport.wrapAlignment) + if (viewport.getWrapAlignment()) { alignPanel.scrollUp(true); } @@ -510,7 +560,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, break; case KeyEvent.VK_PAGE_DOWN: - if (viewport.wrapAlignment) + if (viewport.getWrapAlignment()) { alignPanel.scrollUp(false); } @@ -690,111 +740,188 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, @Override public void itemStateChanged(ItemEvent evt) { - if (evt.getSource() == displayNonconservedMenuItem) + final Object source = evt.getSource(); + if (source == displayNonconservedMenuItem) { displayNonconservedMenuItem_actionPerformed(); } - else if (evt.getSource() == colourTextMenuItem) + else if (source == colourTextMenuItem) { colourTextMenuItem_actionPerformed(); } - else if (evt.getSource() == wrapMenuItem) + else if (source == wrapMenuItem) { wrapMenuItem_actionPerformed(); } - else if (evt.getSource() == scaleAbove) + else if (source == scaleAbove) { viewport.setScaleAboveWrapped(scaleAbove.getState()); } - else if (evt.getSource() == scaleLeft) + else if (source == scaleLeft) { viewport.setScaleLeftWrapped(scaleLeft.getState()); } - else if (evt.getSource() == scaleRight) + else if (source == scaleRight) { viewport.setScaleRightWrapped(scaleRight.getState()); } - else if (evt.getSource() == seqLimits) + else if (source == seqLimits) { seqLimits_itemStateChanged(); } - else if (evt.getSource() == viewBoxesMenuItem) + else if (source == viewBoxesMenuItem) { viewport.setShowBoxes(viewBoxesMenuItem.getState()); } - else if (evt.getSource() == viewTextMenuItem) + else if (source == viewTextMenuItem) { viewport.setShowText(viewTextMenuItem.getState()); } - else if (evt.getSource() == renderGapsMenuItem) + else if (source == renderGapsMenuItem) { viewport.setRenderGaps(renderGapsMenuItem.getState()); } - else if (evt.getSource() == annotationPanelMenuItem) + else if (source == annotationPanelMenuItem) { viewport.setShowAnnotation(annotationPanelMenuItem.getState()); alignPanel.setAnnotationVisible(annotationPanelMenuItem.getState()); } - else if (evt.getSource() == sequenceFeatures) + else if (source == sequenceFeatures) { viewport.setShowSequenceFeatures(sequenceFeatures.getState()); alignPanel.seqPanel.seqCanvas.repaint(); } - else if (evt.getSource() == conservationMenuItem) + else if (source == showAlignmentAnnotations) + { + setAnnotationsVisibility(); + } + else if (source == showSequenceAnnotations) + { + setAnnotationsVisibility(); + } + else if (source == sortAnnBySequence) + { + boolean newState = sortAnnBySequence.getState(); + sortAnnByLabel.setState(false); + setAnnotationSortOrder(newState ? SequenceAnnotationOrder.SEQUENCE_AND_LABEL + : SequenceAnnotationOrder.NONE); + setViewportAnnotationOrder(); + } + else if (source == sortAnnByLabel) + { + boolean newState = sortAnnByLabel.getState(); + sortAnnBySequence.setState(false); + setAnnotationSortOrder(newState ? SequenceAnnotationOrder.LABEL_AND_SEQUENCE + : SequenceAnnotationOrder.NONE); + setViewportAnnotationOrder(); + } + else if (source == showAutoFirst) + { + showAutoLast.setState(!showAutoFirst.getState()); + setShowAutoCalculatedAbove(showAutoFirst.getState()); + setViewportAnnotationOrder(); + } + else if (source == showAutoLast) + { + showAutoFirst.setState(!showAutoLast.getState()); + setShowAutoCalculatedAbove(showAutoFirst.getState()); + setViewportAnnotationOrder(); + } + else if (source == conservationMenuItem) { conservationMenuItem_actionPerformed(); } - else if (evt.getSource() == abovePIDThreshold) + else if (source == abovePIDThreshold) { abovePIDThreshold_actionPerformed(); } - else if (evt.getSource() == applyToAllGroups) + else if (source == applyToAllGroups) { viewport.setColourAppliesToAllGroups(applyToAllGroups.getState()); } - else if (evt.getSource() == autoCalculate) + else if (source == autoCalculate) { viewport.autoCalculateConsensus = autoCalculate.getState(); } - else if (evt.getSource() == sortByTree) + else if (source == sortByTree) { viewport.sortByTree = sortByTree.getState(); } - else if (evt.getSource() == this.centreColumnLabelFlag) + else if (source == this.centreColumnLabelFlag) { centreColumnLabelFlag_stateChanged(); } - else if (evt.getSource() == this.followMouseOverFlag) + else if (source == this.followMouseOverFlag) { mouseOverFlag_stateChanged(); } - else if (evt.getSource() == showGroupConsensus) + else if (source == showGroupConsensus) { showGroupConsensus_actionPerformed(); } - else if (evt.getSource() == showGroupConservation) + else if (source == showGroupConservation) { showGroupConservation_actionPerformed(); } - else if (evt.getSource() == showSequenceLogo) + else if (source == showSequenceLogo) { showSequenceLogo_actionPerformed(); } - else if (evt.getSource() == normSequenceLogo) + else if (source == normSequenceLogo) { normSequenceLogo_actionPerformed(); } - else if (evt.getSource() == showConsensusHistogram) + else if (source == showConsensusHistogram) { showConsensusHistogram_actionPerformed(); } - else if (evt.getSource() == applyAutoAnnotationSettings) + else if (source == applyAutoAnnotationSettings) { applyAutoAnnotationSettings_actionPerformed(); } alignPanel.paintAlignment(true); } + /** + * Set the visibility state of sequence-related and/or alignment-related + * annotations depending on checkbox selections. Repaint after calling. + * + * @param visible + */ + private void setAnnotationsVisibility() + { + boolean showForAlignment = showAlignmentAnnotations.getState(); + boolean showForSequences = showSequenceAnnotations.getState(); + for (AlignmentAnnotation aa : alignPanel.getAlignment() + .getAlignmentAnnotation()) + { + boolean visible = (aa.sequenceRef == null ? showForAlignment + : showForSequences); + aa.visible = visible; + } + alignPanel.validateAnnotationDimensions(false); + } + + private void setAnnotationSortOrder(SequenceAnnotationOrder order) + { + this.annotationSortOrder = order; + } + + /** + * Set flags on the viewport that control annotation ordering + */ + private void setViewportAnnotationOrder() + { + this.alignPanel.av.setSortAnnotationsBy(this.annotationSortOrder); + this.alignPanel.av + .setShowAutocalculatedAbove(this.showAutoCalculatedAbove); + } + + private void setShowAutoCalculatedAbove(boolean showAbove) + { + this.showAutoCalculatedAbove = showAbove; + } + private void mouseOverFlag_stateChanged() { viewport.followHighlight = followMouseOverFlag.getState(); @@ -1181,11 +1308,11 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, Frame frame = new Frame(); frame.add(cap); jalview.bin.JalviewLite.addFrame(frame, MessageManager.formatMessage( - "label.alignment_output_command", new String[] + "label.alignment_output_command", new Object[] { e.getActionCommand() }), 600, 500); cap.setText(new AppletFormatAdapter().formatSequences( e.getActionCommand(), viewport.getAlignment(), - viewport.showJVSuffix)); + viewport.getShowJVSuffix())); } public void loadAnnotations() @@ -1403,12 +1530,12 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, void updateEditMenuBar() { - if (viewport.historyList.size() > 0) + if (viewport.getHistoryList().size() > 0) { undoMenuItem.setEnabled(true); - CommandI command = (CommandI) viewport.historyList.peek(); + CommandI command = viewport.getHistoryList().peek(); undoMenuItem.setLabel(MessageManager.formatMessage( - "label.undo_command", new String[] + "label.undo_command", new Object[] { command.getDescription() })); } else @@ -1417,13 +1544,13 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, undoMenuItem.setLabel(MessageManager.getString("action.undo")); } - if (viewport.redoList.size() > 0) + if (viewport.getRedoList().size() > 0) { redoMenuItem.setEnabled(true); - CommandI command = (CommandI) viewport.redoList.peek(); + CommandI command = viewport.getRedoList().peek(); redoMenuItem.setLabel(MessageManager.formatMessage( - "label.redo_command", new String[] + "label.redo_command", new Object[] { command.getDescription() })); } else @@ -1441,8 +1568,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, { if (command.getSize() > 0) { - viewport.historyList.push(command); - viewport.redoList.removeAllElements(); + viewport.addToHistoryList(command); + viewport.clearRedoList(); updateEditMenuBar(); viewport.updateHiddenColumns(); } @@ -1456,13 +1583,13 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, */ protected void undoMenuItem_actionPerformed() { - if (viewport.historyList.size() < 1) + if (viewport.getHistoryList().isEmpty()) { return; } - CommandI command = (CommandI) viewport.historyList.pop(); - viewport.redoList.push(command); + CommandI command = viewport.getHistoryList().pop(); + viewport.addToRedoList(command); command.undoCommand(null); AlignViewport originalSource = getOriginatingSource(command); @@ -1488,13 +1615,13 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, */ protected void redoMenuItem_actionPerformed() { - if (viewport.redoList.size() < 1) + if (viewport.getRedoList().isEmpty()) { return; } - CommandI command = (CommandI) viewport.redoList.pop(); - viewport.historyList.push(command); + CommandI command = viewport.getRedoList().pop(); + viewport.addToHistoryList(command); command.doCommand(null); AlignViewport originalSource = getOriginatingSource(command); @@ -1554,6 +1681,12 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, return originalSource; } + /** + * Move the currently selected sequences up or down one position in the + * alignment + * + * @param up + */ public void moveSelectedSequences(boolean up) { SequenceGroup sg = viewport.getSelectionGroup(); @@ -1564,6 +1697,21 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, viewport.getAlignment().moveSelectedSequencesByOne(sg, up ? null : viewport.getHiddenRepSequences(), up); alignPanel.paintAlignment(true); + + /* + * Also move cDNA/protein complement sequences + */ + AlignViewportI complement = viewport.getCodingComplement(); + if (complement != null) + { + SequenceGroup mappedSelection = MappingUtils.mapSequenceGroup(sg, + viewport, complement); + complement.getAlignment().moveSelectedSequencesByOne(mappedSelection, + up ? null : complement.getHiddenRepSequences(), up); + // TODO need to trigger a repaint of the complementary panel - how? + // would prefer to handle in SplitFrame but it is not overriding key + // listener chiz + } } synchronized void slideSequences(boolean right, int size) @@ -1651,11 +1799,12 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, } boolean appendHistoryItem = false; - if (viewport.historyList != null && viewport.historyList.size() > 0 - && viewport.historyList.peek() instanceof SlideSequencesCommand) + Deque historyList = viewport.getHistoryList(); + if (historyList != null && historyList.size() > 0 + && historyList.peek() instanceof SlideSequencesCommand) { appendHistoryItem = ssc - .appendSlideCommand((SlideSequencesCommand) viewport.historyList + .appendSlideCommand((SlideSequencesCommand) historyList .peek()); } @@ -1680,12 +1829,12 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, SequenceGroup sg = viewport.getSelectionGroup(); copiedSequences = new StringBuffer(); - Hashtable orderedSeqs = new Hashtable(); + Map orderedSeqs = new HashMap(); for (int i = 0; i < sg.getSize(); i++) { SequenceI seq = sg.getSequenceAt(i); int index = viewport.getAlignment().findIndex(seq); - orderedSeqs.put(index + "", seq); + orderedSeqs.put(index, seq); } int index = 0, startRes, endRes; @@ -1697,7 +1846,6 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, int hiddenOffset = viewport.getSelectionGroup().getStartRes(); for (int[] region : viewport.getColumnSelection().getHiddenColumns()) { - copiedHiddenColumns.addElement(new int[] { region[0] - hiddenOffset, region[1] - hiddenOffset }); } @@ -1713,11 +1861,10 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, while (seq == null) { - if (orderedSeqs.containsKey(index + "")) + if (orderedSeqs.containsKey(index)) { - seq = (SequenceI) orderedSeqs.get(index + ""); + seq = orderedSeqs.get(index); index++; - break; } else @@ -2261,8 +2408,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, newaf.setTitle(title.toString()); - newaf.viewport.historyList = viewport.historyList; - newaf.viewport.redoList = viewport.redoList; + newaf.viewport.setHistoryList(viewport.getHistoryList()); + newaf.viewport.setRedoList(viewport.getRedoList()); return newaf; } @@ -2276,13 +2423,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, if (alignPanel != null && (fr = alignPanel.getFeatureRenderer()) != null) { - List gps = fr.getFeatureGroups(); - int p=0; - String[] _gps = new String[gps.size()]; - for (Object gp:gps) - { - _gps[p++] = gp.toString(); - } + List gps = fr.getFeatureGroups(); + String[] _gps = gps.toArray(new String[gps.size()]); return _gps; } return null; @@ -2301,13 +2443,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, if (alignPanel != null && (fr = alignPanel.getFeatureRenderer()) != null) { - List gps = fr.getGroups(visible); - int p=0; - String[] _gps = new String[gps.size()]; - for (Object gp:gps) - { - _gps[p++] = gp.toString(); - } + List gps = fr.getGroups(visible); + String[] _gps = gps.toArray(new String[gps.size()]); return _gps; } return null; @@ -2354,7 +2491,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, protected void displayNonconservedMenuItem_actionPerformed() { - viewport.setShowunconserved(displayNonconservedMenuItem.getState()); + viewport.setShowUnconserved(displayNonconservedMenuItem.getState()); alignPanel.paintAlignment(true); } @@ -2839,15 +2976,6 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, MenuItem closeMenuItem = new MenuItem( MessageManager.getString("action.close")); - Menu editMenu = new Menu(MessageManager.getString("action.edit")); - - Menu viewMenu = new Menu(MessageManager.getString("action.view")); - - Menu colourMenu = new Menu(MessageManager.getString("action.colour")); - - Menu calculateMenu = new Menu( - MessageManager.getString("action.calculate")); - MenuItem selectAllSequenceMenuItem = new MenuItem( MessageManager.getString("action.select_all")); @@ -2891,8 +3019,6 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, public Label statusBar = new Label(); - Menu outputTextboxMenu = new Menu(); - MenuItem clustalColour = new MenuItem(); MenuItem zappoColour = new MenuItem(); @@ -2990,22 +3116,15 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, MenuItem modifyConservation = new MenuItem(); - CheckboxMenuItem autoCalculate = new CheckboxMenuItem( - "Autocalculate Consensus", true); + CheckboxMenuItem autoCalculate = null; CheckboxMenuItem sortByTree = new CheckboxMenuItem( "Sort Alignment With New Tree", true); Menu sortByTreeMenu = new Menu(); - Menu sort = new Menu(); - - Menu calculate = new Menu(); - MenuItem inputText = new MenuItem(); - Menu helpMenu = new Menu(); - MenuItem documentation = new MenuItem(); MenuItem about = new MenuItem(); @@ -3016,8 +3135,6 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, CheckboxMenuItem followMouseOverFlag = new CheckboxMenuItem(); - Menu autoAnnMenu = new Menu(); - CheckboxMenuItem showSequenceLogo = new CheckboxMenuItem(); CheckboxMenuItem applyAutoAnnotationSettings = new CheckboxMenuItem(); @@ -3030,18 +3147,27 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, CheckboxMenuItem normSequenceLogo = new CheckboxMenuItem(); + /** + * Initialise menus and other items + * + * @throws Exception + */ private void jbInit() throws Exception { - setMenuBar(alignFrameMenuBar); - MenuItem item; - - // dynamically fill save as menu with available formats + /* + * Configure File menu items and actions + */ + inputText + .setLabel(MessageManager.getString("label.input_from_textbox")); + inputText.addActionListener(this); + Menu outputTextboxMenu = new Menu( + MessageManager.getString("label.out_to_textbox")); for (int i = 0; i < jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS.length; i++) { - item = new MenuItem( + MenuItem item = new MenuItem( jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS[i]); item.addActionListener(new java.awt.event.ActionListener() @@ -3057,14 +3183,31 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, } closeMenuItem.addActionListener(this); loadApplication.addActionListener(this); - loadTree.addActionListener(this); loadAnnotations.addActionListener(this); outputFeatures.addActionListener(this); outputAnnotations.addActionListener(this); - selectAllSequenceMenuItem.addActionListener(this); - deselectAllSequenceMenuItem.addActionListener(this); - invertSequenceMenuItem.addActionListener(this); + + /* + * Configure Edit menu items and actions + */ + undoMenuItem.setEnabled(false); + undoMenuItem.setLabel(MessageManager.getString("action.undo")); + undoMenuItem.addActionListener(this); + redoMenuItem.setEnabled(false); + redoMenuItem.setLabel(MessageManager.getString("action.redo")); + redoMenuItem.addActionListener(this); + copy.setLabel(MessageManager.getString("action.copy")); + copy.addActionListener(this); + cut.setLabel(MessageManager.getString("action.cut")); + cut.addActionListener(this); + delete.setLabel(MessageManager.getString("action.delete")); + delete.addActionListener(this); + pasteMenu.setLabel(MessageManager.getString("action.paste")); + pasteNew.setLabel(MessageManager.getString("label.to_new_alignment")); + pasteNew.addActionListener(this); + pasteThis.setLabel(MessageManager.getString("label.to_this_alignment")); + pasteThis.addActionListener(this); remove2LeftMenuItem.setLabel(MessageManager .getString("action.remove_left")); remove2LeftMenuItem.addActionListener(this); @@ -3077,128 +3220,23 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, removeAllGapsMenuItem.setLabel(MessageManager .getString("action.remove_all_gaps")); removeAllGapsMenuItem.addActionListener(this); - viewBoxesMenuItem.setLabel(MessageManager.getString("action.boxes")); - viewBoxesMenuItem.setState(true); - viewBoxesMenuItem.addItemListener(this); - viewTextMenuItem.setLabel(MessageManager.getString("action.text")); - viewTextMenuItem.setState(true); - viewTextMenuItem.addItemListener(this); - sortPairwiseMenuItem.setLabel(MessageManager - .getString("action.by_pairwise_id")); - sortPairwiseMenuItem.addActionListener(this); - sortIDMenuItem.setLabel(MessageManager.getString("action.by_id")); - sortIDMenuItem.addActionListener(this); - sortLengthMenuItem.setLabel(MessageManager - .getString("action.by_length")); - sortLengthMenuItem.addActionListener(this); - sortGroupMenuItem.setLabel(MessageManager.getString("action.by_group")); - sortGroupMenuItem.addActionListener(this); - removeRedundancyMenuItem.setLabel(MessageManager - .getString("action.remove_redundancy").concat("...")); + removeRedundancyMenuItem.setLabel(MessageManager.getString( + "action.remove_redundancy").concat("...")); removeRedundancyMenuItem.addActionListener(this); - pairwiseAlignmentMenuItem.setLabel(MessageManager - .getString("action.pairwise_alignment")); - pairwiseAlignmentMenuItem.addActionListener(this); - PCAMenuItem.setLabel(MessageManager - .getString("label.principal_component_analysis")); - PCAMenuItem.addActionListener(this); - averageDistanceTreeMenuItem.setLabel(MessageManager - .getString("label.average_distance_identity")); - averageDistanceTreeMenuItem.addActionListener(this); - neighbourTreeMenuItem.setLabel(MessageManager - .getString("label.neighbour_joining_identity")); - neighbourTreeMenuItem.addActionListener(this); - statusBar.setBackground(Color.white); - statusBar.setFont(new java.awt.Font("Verdana", 0, 11)); - statusBar.setText(MessageManager.getString("label.status_bar")); - outputTextboxMenu.setLabel(MessageManager - .getString("label.out_to_textbox")); - clustalColour.setLabel(MessageManager.getString("label.clustalx")); - clustalColour.addActionListener(this); - zappoColour.setLabel(MessageManager.getString("label.zappo")); - zappoColour.addActionListener(this); - taylorColour.setLabel(MessageManager.getString("label.taylor")); - taylorColour.addActionListener(this); - hydrophobicityColour.setLabel(MessageManager - .getString("label.hydrophobicity")); - hydrophobicityColour.addActionListener(this); - helixColour - .setLabel(MessageManager.getString("label.helix_propensity")); - helixColour.addActionListener(this); - strandColour.setLabel(MessageManager - .getString("label.strand_propensity")); - strandColour.addActionListener(this); - turnColour.setLabel(MessageManager.getString("label.turn_propensity")); - turnColour.addActionListener(this); - buriedColour.setLabel(MessageManager.getString("label.buried_index")); - buriedColour.addActionListener(this); - purinePyrimidineColour.setLabel(MessageManager - .getString("label.purine_pyrimidine")); - purinePyrimidineColour.addActionListener(this); - RNAInteractionColour.setLabel(MessageManager - .getString("label.rna_interaction")); - RNAInteractionColour.addActionListener(this); - RNAHelixColour.setLabel(MessageManager - .getString("action.by_rna_helixes")); - RNAHelixColour.addActionListener(this); - userDefinedColour.setLabel(MessageManager - .getString("action.user_defined")); - userDefinedColour.addActionListener(this); - PIDColour.setLabel(MessageManager - .getString("label.percentage_identity")); - PIDColour.addActionListener(this); - BLOSUM62Colour.setLabel(MessageManager - .getString("label.blosum62_score")); - BLOSUM62Colour.addActionListener(this); - tcoffeeColour - .setLabel(MessageManager.getString("label.tcoffee_scores")); - tcoffeeColour.setEnabled(false); // it will enabled only if a score file is - // provided - tcoffeeColour.addActionListener(this); - avDistanceTreeBlosumMenuItem.setLabel(MessageManager - .getString("label.average_distance_bloslum62")); - avDistanceTreeBlosumMenuItem.addActionListener(this); - njTreeBlosumMenuItem.setLabel(MessageManager - .getString("label.neighbour_blosum62")); - njTreeBlosumMenuItem.addActionListener(this); - annotationPanelMenuItem.setLabel(MessageManager - .getString("label.show_annotations")); - annotationPanelMenuItem.addItemListener(this); - colourTextMenuItem.setLabel(MessageManager - .getString("label.colour_text")); - colourTextMenuItem.addItemListener(this); - displayNonconservedMenuItem.setLabel(MessageManager - .getString("label.show_non_conversed")); - displayNonconservedMenuItem.addItemListener(this); - alProperties.addActionListener(this); - overviewMenuItem.setLabel(MessageManager - .getString("label.overview_window")); - overviewMenuItem.addActionListener(this); - undoMenuItem.setEnabled(false); - undoMenuItem.setLabel(MessageManager.getString("action.undo")); - undoMenuItem.addActionListener(this); - redoMenuItem.setEnabled(false); - redoMenuItem.setLabel(MessageManager.getString("action.redo")); - redoMenuItem.addActionListener(this); - conservationMenuItem.setLabel(MessageManager - .getString("action.by_conservation")); - conservationMenuItem.addItemListener(this); - noColourmenuItem.setLabel(MessageManager.getString("label.none")); - noColourmenuItem.addActionListener(this); - wrapMenuItem.setLabel(MessageManager.getString("action.wrap")); - wrapMenuItem.addItemListener(this); - renderGapsMenuItem.setLabel(MessageManager - .getString("action.show_gaps")); - renderGapsMenuItem.setState(true); - renderGapsMenuItem.addItemListener(this); + /* + * Configure Select menu items and actions + */ findMenuItem.setLabel(MessageManager.getString("action.find")); findMenuItem.addActionListener(this); - abovePIDThreshold.setLabel(MessageManager - .getString("label.above_identity_threshold")); - abovePIDThreshold.addItemListener(this); - nucleotideColour.setLabel(MessageManager.getString("label.nucleotide")); - nucleotideColour.addActionListener(this); + selectAllSequenceMenuItem.addActionListener(this); + deselectAllSequenceMenuItem.addActionListener(this); + invertSequenceMenuItem.setLabel(MessageManager + .getString("action.invert_sequence_selection")); + invertSequenceMenuItem.addActionListener(this); + invertColSel.setLabel(MessageManager + .getString("action.invert_column_selection")); + invertColSel.addActionListener(this); deleteGroups.setLabel(MessageManager .getString("action.undefine_groups")); deleteGroups.addActionListener(this); @@ -3207,88 +3245,18 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, grpsFromSelection.addActionListener(this); createGroup.setLabel(MessageManager.getString("action.create_group")); unGroup.setLabel(MessageManager.getString("action.remove_group")); - copy.setLabel(MessageManager.getString("action.copy")); - copy.addActionListener(this); - cut.setLabel(MessageManager.getString("action.cut")); - cut.addActionListener(this); - delete.setLabel(MessageManager.getString("action.delete")); - delete.addActionListener(this); - pasteMenu.setLabel(MessageManager.getString("action.paste")); - pasteNew.setLabel(MessageManager.getString("label.to_new_alignment")); - pasteNew.addActionListener(this); - pasteThis.setLabel(MessageManager.getString("label.to_this_alignment")); - pasteThis.addActionListener(this); - applyToAllGroups.setLabel(MessageManager - .getString("label.apply_colour_to_all_groups")); - applyToAllGroups.setState(true); - applyToAllGroups.addItemListener(this); - font.setLabel(MessageManager.getString("action.font")); - font.addActionListener(this); - scaleAbove.setLabel(MessageManager.getString("action.scale_above")); - scaleAbove.setState(true); - scaleAbove.setEnabled(false); - scaleAbove.addItemListener(this); - scaleLeft.setEnabled(false); - scaleLeft.setState(true); - scaleLeft.setLabel(MessageManager.getString("action.scale_left")); - scaleLeft.addItemListener(this); - scaleRight.setEnabled(false); - scaleRight.setState(true); - scaleRight.setLabel(MessageManager.getString("action.scale_right")); - scaleRight.addItemListener(this); - modifyPID.setLabel(MessageManager - .getString("label.modify_identity_thereshold")); - modifyPID.addActionListener(this); - modifyConservation.setLabel(MessageManager - .getString("label.modify_conservation_thereshold")); - modifyConservation.addActionListener(this); - sortByTreeMenu.setLabel(MessageManager - .getString("action.by_tree_order")); - sort.setLabel(MessageManager.getString("action.sort")); - calculate.setLabel(MessageManager.getString("action.calculate_tree")); - autoCalculate.addItemListener(this); - sortByTree.addItemListener(this); - inputText - .setLabel(MessageManager.getString("label.input_from_textbox")); - inputText.addActionListener(this); - centreColumnLabelFlag.setLabel(MessageManager - .getString("label.centre_column_labels")); - centreColumnLabelFlag.addItemListener(this); - followMouseOverFlag.setLabel(MessageManager - .getString("label.automatic_scrolling")); - followMouseOverFlag.addItemListener(this); - helpMenu.setLabel(MessageManager.getString("action.help")); - documentation.setLabel(MessageManager.getString("label.documentation")); - documentation.addActionListener(this); - - about.setLabel(MessageManager.getString("label.about")); - about.addActionListener(this); - seqLimits.setState(true); - seqLimits.setLabel(MessageManager - .getString("label.show_sequence_limits")); - seqLimits.addItemListener(this); - featureSettings.setLabel(MessageManager - .getString("label.feature_settings")); - featureSettings.addActionListener(this); - sequenceFeatures.setLabel(MessageManager - .getString("label.sequence_features")); - sequenceFeatures.addItemListener(this); - sequenceFeatures.setState(false); - annotationColour.setLabel(MessageManager - .getString("action.by_annotation")); - annotationColour.addActionListener(this); - annotationColumnSelection.setLabel("Select by Annotation"); annotationColumnSelection.addActionListener(this); - invertSequenceMenuItem.setLabel(MessageManager - .getString("action.invert_sequence_selection")); - invertColSel.setLabel(MessageManager - .getString("action.invert_column_selection")); - menu1.setLabel(MessageManager.getString("action.show")); + /* + * Configure View menu items and actions + */ + newView.setLabel(MessageManager.getString("action.new_view")); + newView.addActionListener(this); + Menu showMenu = new Menu(MessageManager.getString("action.show")); showColumns.setLabel(MessageManager.getString("label.all_columns")); showSeqs.setLabel(MessageManager.getString("label.all_sequences")); - menu2.setLabel(MessageManager.getString("action.hide")); + Menu hideMenu = new Menu(MessageManager.getString("action.hide")); hideColumns .setLabel(MessageManager.getString("label.selected_columns")); hideSequences.setLabel(MessageManager @@ -3299,6 +3267,34 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, .getString("label.selected_region")); showAllHidden.setLabel(MessageManager .getString("label.all_sequences_columns")); + showColumns.addActionListener(this); + showSeqs.addActionListener(this); + hideColumns.addActionListener(this); + hideSequences.addActionListener(this); + hideAllButSelection.addActionListener(this); + hideAllSelection.addActionListener(this); + showAllHidden.addActionListener(this); + featureSettings.setLabel(MessageManager + .getString("label.feature_settings")); + featureSettings.addActionListener(this); + sequenceFeatures.setLabel(MessageManager + .getString("label.show_sequence_features")); + sequenceFeatures.addItemListener(this); + sequenceFeatures.setState(false); + followMouseOverFlag.setLabel(MessageManager + .getString("label.automatic_scrolling")); + followMouseOverFlag.addItemListener(this); + alProperties.addActionListener(this); + overviewMenuItem.setLabel(MessageManager + .getString("label.overview_window")); + overviewMenuItem.addActionListener(this); + + /* + * Configure Annotations menu items and actions + */ + annotationPanelMenuItem.setLabel(MessageManager + .getString("label.show_annotations")); + annotationPanelMenuItem.addItemListener(this); showGroupConsensus.setLabel(MessageManager .getString("label.group_consensus")); showGroupConservation.setLabel(MessageManager @@ -3312,58 +3308,243 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, applyAutoAnnotationSettings.setLabel(MessageManager .getString("label.apply_all_groups")); applyAutoAnnotationSettings.setState(true); - autoAnnMenu.setLabel(MessageManager - .getString("label.autocalculated_annotation")); - - invertColSel.addActionListener(this); - showColumns.addActionListener(this); - showSeqs.addActionListener(this); - hideColumns.addActionListener(this); - hideSequences.addActionListener(this); - hideAllButSelection.addActionListener(this); - hideAllSelection.addActionListener(this); - showAllHidden.addActionListener(this); + Menu autoAnnMenu = new Menu( + MessageManager.getString("label.autocalculated_annotation")); showGroupConsensus.addItemListener(this); showGroupConservation.addItemListener(this); showConsensusHistogram.addItemListener(this); showSequenceLogo.addItemListener(this); normSequenceLogo.addItemListener(this); - applyAutoAnnotationSettings.addItemListener(this); - formatMenu.setLabel(MessageManager.getString("action.format")); - selectMenu.setLabel(MessageManager.getString("action.select")); - newView.setLabel(MessageManager.getString("action.new_view")); - newView.addActionListener(this); + showAlignmentAnnotations = new CheckboxMenuItem( + MessageManager.getString("label.show_all_al_annotations")); + showSequenceAnnotations = new CheckboxMenuItem( + MessageManager.getString("label.show_all_seq_annotations")); + sortAnnBySequence = new CheckboxMenuItem( + MessageManager.getString("label.sort_annotations_by_sequence")); + sortAnnByLabel = new CheckboxMenuItem( + MessageManager.getString("label.sort_annotations_by_label")); + showAutoFirst = new CheckboxMenuItem( + MessageManager.getString("label.show_first")); + showAutoLast = new CheckboxMenuItem( + MessageManager.getString("label.show_last")); + showAlignmentAnnotations.addItemListener(this); + showSequenceAnnotations.addItemListener(this); + sortAnnBySequence.addItemListener(this); + sortAnnByLabel.addItemListener(this); + showAutoFirst.addItemListener(this); + showAutoLast.addItemListener(this); + + /* + * Configure Format menu items and actions + */ + font.setLabel(MessageManager.getString("action.font")); + font.addActionListener(this); + scaleAbove.setLabel(MessageManager.getString("action.scale_above")); + scaleAbove.setState(true); + scaleAbove.setEnabled(false); + scaleAbove.addItemListener(this); + scaleLeft.setEnabled(false); + scaleLeft.setState(true); + scaleLeft.setLabel(MessageManager.getString("action.scale_left")); + scaleLeft.addItemListener(this); + scaleRight.setEnabled(false); + scaleRight.setState(true); + scaleRight.setLabel(MessageManager.getString("action.scale_right")); + scaleRight.addItemListener(this); + viewBoxesMenuItem.setLabel(MessageManager.getString("action.boxes")); + viewBoxesMenuItem.setState(true); + viewBoxesMenuItem.addItemListener(this); + viewTextMenuItem.setLabel(MessageManager.getString("action.text")); + viewTextMenuItem.setState(true); + viewTextMenuItem.addItemListener(this); + colourTextMenuItem.setLabel(MessageManager + .getString("label.colour_text")); + colourTextMenuItem.addItemListener(this); + displayNonconservedMenuItem.setLabel(MessageManager + .getString("label.show_non_conversed")); + displayNonconservedMenuItem.addItemListener(this); + wrapMenuItem.setLabel(MessageManager.getString("action.wrap")); + wrapMenuItem.addItemListener(this); + renderGapsMenuItem.setLabel(MessageManager + .getString("action.show_gaps")); + renderGapsMenuItem.setState(true); + renderGapsMenuItem.addItemListener(this); + centreColumnLabelFlag.setLabel(MessageManager + .getString("label.centre_column_labels")); + centreColumnLabelFlag.addItemListener(this); + seqLimits.setState(true); + seqLimits.setLabel(MessageManager + .getString("label.show_sequence_limits")); + seqLimits.addItemListener(this); + + /* + * Configure Colour menu items and actions + */ + applyToAllGroups.setLabel(MessageManager + .getString("label.apply_colour_to_all_groups")); + applyToAllGroups.setState(true); + applyToAllGroups.addItemListener(this); + clustalColour.setLabel(MessageManager.getString("label.clustalx")); + clustalColour.addActionListener(this); + zappoColour.setLabel(MessageManager.getString("label.zappo")); + zappoColour.addActionListener(this); + taylorColour.setLabel(MessageManager.getString("label.taylor")); + taylorColour.addActionListener(this); + hydrophobicityColour.setLabel(MessageManager + .getString("label.hydrophobicity")); + hydrophobicityColour.addActionListener(this); + helixColour + .setLabel(MessageManager.getString("label.helix_propensity")); + helixColour.addActionListener(this); + strandColour.setLabel(MessageManager + .getString("label.strand_propensity")); + strandColour.addActionListener(this); + turnColour.setLabel(MessageManager.getString("label.turn_propensity")); + turnColour.addActionListener(this); + buriedColour.setLabel(MessageManager.getString("label.buried_index")); + buriedColour.addActionListener(this); + purinePyrimidineColour.setLabel(MessageManager + .getString("label.purine_pyrimidine")); + purinePyrimidineColour.addActionListener(this); + RNAInteractionColour.setLabel(MessageManager + .getString("label.rna_interaction")); + RNAInteractionColour.addActionListener(this); + RNAHelixColour.setLabel(MessageManager + .getString("action.by_rna_helixes")); + RNAHelixColour.addActionListener(this); + userDefinedColour.setLabel(MessageManager + .getString("action.user_defined")); + userDefinedColour.addActionListener(this); + PIDColour.setLabel(MessageManager + .getString("label.percentage_identity")); + PIDColour.addActionListener(this); + BLOSUM62Colour.setLabel(MessageManager + .getString("label.blosum62_score")); + BLOSUM62Colour.addActionListener(this); + tcoffeeColour + .setLabel(MessageManager.getString("label.tcoffee_scores")); + // it will be enabled only if a score file is provided + tcoffeeColour.setEnabled(false); + tcoffeeColour.addActionListener(this); + conservationMenuItem.setLabel(MessageManager + .getString("action.by_conservation")); + conservationMenuItem.addItemListener(this); + noColourmenuItem.setLabel(MessageManager.getString("label.none")); + noColourmenuItem.addActionListener(this); + abovePIDThreshold.setLabel(MessageManager + .getString("label.above_identity_threshold")); + abovePIDThreshold.addItemListener(this); + nucleotideColour.setLabel(MessageManager.getString("label.nucleotide")); + nucleotideColour.addActionListener(this); + modifyPID.setLabel(MessageManager + .getString("label.modify_identity_thereshold")); + modifyPID.addActionListener(this); + modifyConservation.setLabel(MessageManager + .getString("label.modify_conservation_thereshold")); + modifyConservation.addActionListener(this); + annotationColour.setLabel(MessageManager + .getString("action.by_annotation")); + annotationColour.addActionListener(this); + + /* + * Configure Calculate menu items and actions + */ + sortPairwiseMenuItem.setLabel(MessageManager + .getString("action.by_pairwise_id")); + sortPairwiseMenuItem.addActionListener(this); + sortIDMenuItem.setLabel(MessageManager.getString("action.by_id")); + sortIDMenuItem.addActionListener(this); + sortLengthMenuItem.setLabel(MessageManager + .getString("action.by_length")); + sortLengthMenuItem.addActionListener(this); + sortGroupMenuItem.setLabel(MessageManager.getString("action.by_group")); + sortGroupMenuItem.addActionListener(this); + pairwiseAlignmentMenuItem.setLabel(MessageManager + .getString("action.pairwise_alignment")); + pairwiseAlignmentMenuItem.addActionListener(this); + PCAMenuItem.setLabel(MessageManager + .getString("label.principal_component_analysis")); + PCAMenuItem.addActionListener(this); + autoCalculate = new CheckboxMenuItem( + MessageManager.getString("label.autocalculate_consensus"), true); + averageDistanceTreeMenuItem.setLabel(MessageManager + .getString("label.average_distance_identity")); + averageDistanceTreeMenuItem.addActionListener(this); + neighbourTreeMenuItem.setLabel(MessageManager + .getString("label.neighbour_joining_identity")); + neighbourTreeMenuItem.addActionListener(this); + avDistanceTreeBlosumMenuItem.setLabel(MessageManager + .getString("label.average_distance_bloslum62")); + avDistanceTreeBlosumMenuItem.addActionListener(this); + njTreeBlosumMenuItem.setLabel(MessageManager + .getString("label.neighbour_blosum62")); + njTreeBlosumMenuItem.addActionListener(this); + sortByTreeMenu.setLabel(MessageManager + .getString("action.by_tree_order")); + Menu sortMenu = new Menu(MessageManager.getString("action.sort")); + Menu calculateTreeMenu = new Menu( + MessageManager.getString("action.calculate_tree")); + autoCalculate.addItemListener(this); + sortByTree.addItemListener(this); + + /* + * Configure Help menu items and actions + */ + Menu helpMenu = new Menu(MessageManager.getString("action.help")); + documentation.setLabel(MessageManager.getString("label.documentation")); + documentation.addActionListener(this); + about.setLabel(MessageManager.getString("label.about")); + about.addActionListener(this); + + /* + * Add top level menus to frame + */ alignFrameMenuBar.add(fileMenu); + Menu editMenu = new Menu(MessageManager.getString("action.edit")); alignFrameMenuBar.add(editMenu); + Menu selectMenu = new Menu(MessageManager.getString("action.select")); alignFrameMenuBar.add(selectMenu); + Menu viewMenu = new Menu(MessageManager.getString("action.view")); alignFrameMenuBar.add(viewMenu); + Menu annotationsMenu = new Menu( + MessageManager.getString("action.annotations")); + alignFrameMenuBar.add(annotationsMenu); + Menu formatMenu = new Menu(MessageManager.getString("action.format")); alignFrameMenuBar.add(formatMenu); + Menu colourMenu = new Menu(MessageManager.getString("action.colour")); alignFrameMenuBar.add(colourMenu); + Menu calculateMenu = new Menu( + MessageManager.getString("action.calculate")); alignFrameMenuBar.add(calculateMenu); alignFrameMenuBar.add(helpMenu); + /* + * File menu + */ fileMenu.add(inputText); fileMenu.add(loadTree); fileMenu.add(loadAnnotations); - fileMenu.addSeparator(); fileMenu.add(outputTextboxMenu); fileMenu.add(outputFeatures); fileMenu.add(outputAnnotations); - if (jalviewServletURL != null) { fileMenu.add(loadApplication); } - fileMenu.addSeparator(); fileMenu.add(closeMenuItem); + /* + * Edit menu + */ editMenu.add(undoMenuItem); editMenu.add(redoMenuItem); editMenu.add(cut); editMenu.add(copy); + pasteMenu.add(pasteNew); + pasteMenu.add(pasteThis); editMenu.add(pasteMenu); editMenu.add(delete); editMenu.addSeparator(); @@ -3372,21 +3553,38 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, editMenu.add(removeGappedColumnMenuItem); editMenu.add(removeAllGapsMenuItem); editMenu.add(removeRedundancyMenuItem); + + /* + * Select menu + */ + selectMenu.add(findMenuItem); + selectMenu.addSeparator(); + selectMenu.add(selectAllSequenceMenuItem); + selectMenu.add(deselectAllSequenceMenuItem); + selectMenu.add(invertSequenceMenuItem); + selectMenu.add(invertColSel); + selectMenu.add(createGroup); + selectMenu.add(unGroup); + selectMenu.add(grpsFromSelection); + selectMenu.add(deleteGroups); + selectMenu.add(annotationColumnSelection); + + /* + * View menu + */ viewMenu.add(newView); viewMenu.addSeparator(); - viewMenu.add(menu1); - viewMenu.add(menu2); + showMenu.add(showColumns); + showMenu.add(showSeqs); + showMenu.add(showAllHidden); + viewMenu.add(showMenu); + hideMenu.add(hideColumns); + hideMenu.add(hideSequences); + hideMenu.add(hideAllSelection); + hideMenu.add(hideAllButSelection); + viewMenu.add(hideMenu); viewMenu.addSeparator(); viewMenu.add(followMouseOverFlag); - viewMenu.add(annotationPanelMenuItem); - autoAnnMenu.add(applyAutoAnnotationSettings); - autoAnnMenu.add(showConsensusHistogram); - autoAnnMenu.add(showSequenceLogo); - autoAnnMenu.add(normSequenceLogo); - autoAnnMenu.addSeparator(); - autoAnnMenu.add(showGroupConservation); - autoAnnMenu.add(showGroupConsensus); - viewMenu.add(autoAnnMenu); viewMenu.addSeparator(); viewMenu.add(sequenceFeatures); viewMenu.add(featureSettings); @@ -3394,6 +3592,48 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, viewMenu.add(alProperties); viewMenu.addSeparator(); viewMenu.add(overviewMenuItem); + + /* + * Annotations menu + */ + // annotationsMenu.add(annotationPanelMenuItem); + // annotationsMenu.addSeparator(); + annotationsMenu.add(showAlignmentAnnotations); + annotationsMenu.add(showSequenceAnnotations); + annotationsMenu.add(sortAnnBySequence); + annotationsMenu.add(sortAnnByLabel); + annotationsMenu.addSeparator(); + autoAnnMenu.add(showAutoFirst); + autoAnnMenu.add(showAutoLast); + autoAnnMenu.addSeparator(); + autoAnnMenu.add(applyAutoAnnotationSettings); + autoAnnMenu.add(showConsensusHistogram); + autoAnnMenu.add(showSequenceLogo); + autoAnnMenu.add(normSequenceLogo); + autoAnnMenu.addSeparator(); + autoAnnMenu.add(showGroupConservation); + autoAnnMenu.add(showGroupConsensus); + annotationsMenu.add(autoAnnMenu); + + /* + * Format menu + */ + formatMenu.add(font); + formatMenu.add(seqLimits); + formatMenu.add(wrapMenuItem); + formatMenu.add(scaleAbove); + formatMenu.add(scaleLeft); + formatMenu.add(scaleRight); + formatMenu.add(viewBoxesMenuItem); + formatMenu.add(viewTextMenuItem); + formatMenu.add(colourTextMenuItem); + formatMenu.add(displayNonconservedMenuItem); + formatMenu.add(renderGapsMenuItem); + formatMenu.add(centreColumnLabelFlag); + + /* + * Colour menu + */ colourMenu.add(applyToAllGroups); colourMenu.addSeparator(); colourMenu.add(noColourmenuItem); @@ -3419,58 +3659,40 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, colourMenu.add(modifyPID); colourMenu.add(annotationColour); colourMenu.add(RNAHelixColour); - calculateMenu.add(sort); - calculateMenu.add(calculate); + + /* + * Calculate menu + */ + sortMenu.add(sortIDMenuItem); + sortMenu.add(sortLengthMenuItem); + sortMenu.add(sortByTreeMenu); + sortMenu.add(sortGroupMenuItem); + sortMenu.add(sortPairwiseMenuItem); + calculateMenu.add(sortMenu); + calculateTreeMenu.add(averageDistanceTreeMenuItem); + calculateTreeMenu.add(neighbourTreeMenuItem); + calculateTreeMenu.add(avDistanceTreeBlosumMenuItem); + calculateTreeMenu.add(njTreeBlosumMenuItem); + calculateMenu.add(calculateTreeMenu); calculateMenu.addSeparator(); calculateMenu.add(pairwiseAlignmentMenuItem); calculateMenu.add(PCAMenuItem); calculateMenu.add(autoCalculate); calculateMenu.add(sortByTree); - this.add(statusBar, BorderLayout.SOUTH); - pasteMenu.add(pasteNew); - pasteMenu.add(pasteThis); - sort.add(sortIDMenuItem); - sort.add(sortLengthMenuItem); - sort.add(sortByTreeMenu); - sort.add(sortGroupMenuItem); - sort.add(sortPairwiseMenuItem); - calculate.add(averageDistanceTreeMenuItem); - calculate.add(neighbourTreeMenuItem); - calculate.add(avDistanceTreeBlosumMenuItem); - calculate.add(njTreeBlosumMenuItem); + + /* + * Help menu + */ helpMenu.add(documentation); helpMenu.add(about); - menu1.add(showColumns); - menu1.add(showSeqs); - menu1.add(showAllHidden); - menu2.add(hideColumns); - menu2.add(hideSequences); - menu2.add(hideAllSelection); - menu2.add(hideAllButSelection); - formatMenu.add(font); - formatMenu.add(seqLimits); - formatMenu.add(wrapMenuItem); - formatMenu.add(scaleAbove); - formatMenu.add(scaleLeft); - formatMenu.add(scaleRight); - formatMenu.add(viewBoxesMenuItem); - formatMenu.add(viewTextMenuItem); - formatMenu.add(colourTextMenuItem); - formatMenu.add(displayNonconservedMenuItem); - formatMenu.add(renderGapsMenuItem); - formatMenu.add(centreColumnLabelFlag); - selectMenu.add(findMenuItem); - selectMenu.addSeparator(); - selectMenu.add(selectAllSequenceMenuItem); - selectMenu.add(deselectAllSequenceMenuItem); - selectMenu.add(invertSequenceMenuItem); - selectMenu.add(invertColSel); - selectMenu.add(createGroup); - selectMenu.add(unGroup); - selectMenu.add(grpsFromSelection); - selectMenu.add(deleteGroups); - selectMenu.add(annotationColumnSelection); + /* + * Status bar + */ + statusBar.setBackground(Color.white); + statusBar.setFont(new java.awt.Font("Verdana", 0, 11)); + statusBar.setText(MessageManager.getString("label.status_bar")); + this.add(statusBar, BorderLayout.SOUTH); } public void setStatus(String string) @@ -3488,14 +3710,10 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, MenuItem invertColSel = new MenuItem(); - Menu menu1 = new Menu(); - MenuItem showColumns = new MenuItem(); MenuItem showSeqs = new MenuItem(); - Menu menu2 = new Menu(); - MenuItem hideColumns = new MenuItem(); MenuItem hideSequences = new MenuItem(); @@ -3506,11 +3724,19 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, MenuItem showAllHidden = new MenuItem(); - Menu formatMenu = new Menu(); + MenuItem newView = new MenuItem(); - Menu selectMenu = new Menu(); + private CheckboxMenuItem showAlignmentAnnotations; - MenuItem newView = new MenuItem(); + private CheckboxMenuItem showSequenceAnnotations; + + private CheckboxMenuItem sortAnnBySequence; + + private CheckboxMenuItem sortAnnByLabel; + + private CheckboxMenuItem showAutoFirst; + + private CheckboxMenuItem showAutoLast; /** * Attach the alignFrame panels after embedding menus, if necessary. This used @@ -3521,46 +3747,11 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, * true to attach the view to the applet area on the page rather than * in a new window */ - public void createAlignFrameWindow(boolean reallyEmbedded, String title) + public void createAlignFrameWindow(boolean reallyEmbedded) { if (reallyEmbedded) { - // //// - // Explicly build the embedded menu panel for the on-page applet - // - // view cannot be closed if its actually on the page - fileMenu.remove(closeMenuItem); - fileMenu.remove(3); // Remove Seperator - embeddedMenu = makeEmbeddedPopupMenu(alignFrameMenuBar, "Arial", - Font.PLAIN, 11, false); // use our own fonts. - // and actually add the components to the applet area - viewport.applet.setLayout(new BorderLayout()); - viewport.applet.add(embeddedMenu, BorderLayout.NORTH); - viewport.applet.add(statusBar, BorderLayout.SOUTH); - alignPanel.setSize(viewport.applet.getSize().width, - viewport.applet.getSize().height - embeddedMenu.HEIGHT - - statusBar.HEIGHT); - viewport.applet.add(alignPanel, BorderLayout.CENTER); - final AlignFrame me = this; - viewport.applet.addFocusListener(new FocusListener() - { - - @Override - public void focusLost(FocusEvent e) - { - if (me.viewport.applet.currentAlignFrame == me) - { - me.viewport.applet.currentAlignFrame = null; - } - } - - @Override - public void focusGained(FocusEvent e) - { - me.viewport.applet.currentAlignFrame = me; - } - }); - viewport.applet.validate(); + embedAlignFrameInApplet(viewport.applet); } else { @@ -3569,19 +3760,69 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, // if (embedMenuIfNeeded(alignPanel)) { - // adjust for status bar height too - alignPanel.setSize(getSize().width, getSize().height - - statusBar.HEIGHT); + /* + * adjust for status bar height too. ? pointless as overridden by layout + * manager + */ + alignPanel.setSize(getSize().width, + getSize().height - statusBar.getHeight()); } add(statusBar, BorderLayout.SOUTH); add(alignPanel, BorderLayout.CENTER); // and register with the applet so it can pass external API calls to us - jalview.bin.JalviewLite.addFrame(this, title, DEFAULT_WIDTH, + jalview.bin.JalviewLite.addFrame(this, this.getTitle(), + DEFAULT_WIDTH, DEFAULT_HEIGHT); } } /** + * Add the components of this AlignFrame to the applet container. + * + * @param theApplet + */ + public void embedAlignFrameInApplet(final JalviewLite theApplet) + { + // //// + // Explicitly build the embedded menu panel for the on-page applet + // + // view cannot be closed if its actually on the page + fileMenu.remove(closeMenuItem); + fileMenu.remove(3); // Remove Separator + // construct embedded menu, using default font + embeddedMenu = makeEmbeddedPopupMenu(alignFrameMenuBar, false, false); + // and actually add the components to the applet area + theApplet.setLayout(new BorderLayout()); + theApplet.add(embeddedMenu, BorderLayout.NORTH); + theApplet.add(statusBar, BorderLayout.SOUTH); + // TODO should size be left to the layout manager? + alignPanel.setSize(theApplet.getSize().width, + theApplet.getSize().height - embeddedMenu.getHeight() + - statusBar.getHeight()); + theApplet.add(alignPanel, BorderLayout.CENTER); + final AlignFrame me = this; + theApplet.addFocusListener(new FocusListener() + { + + @Override + public void focusLost(FocusEvent e) + { + if (theApplet.currentAlignFrame == me) + { + theApplet.currentAlignFrame = null; + } + } + + @Override + public void focusGained(FocusEvent e) + { + theApplet.currentAlignFrame = me; + } + }); + theApplet.validate(); + } + + /** * create a new binding between structures in an existing jmol viewer instance * and an alignpanel with sequences that have existing PDBFile entries. Note, * this does not open a new Jmol window, or modify the display of the diff --git a/src/jalview/appletgui/AlignViewport.java b/src/jalview/appletgui/AlignViewport.java index 7cf7be0..2d38008 100644 --- a/src/jalview/appletgui/AlignViewport.java +++ b/src/jalview/appletgui/AlignViewport.java @@ -20,9 +20,12 @@ */ package jalview.appletgui; +import java.awt.Font; + import jalview.analysis.NJTree; import jalview.api.AlignViewportI; import jalview.bin.JalviewLite; +import jalview.commands.CommandI; import jalview.datamodel.AlignmentI; import jalview.datamodel.ColumnSelection; import jalview.datamodel.Sequence; @@ -30,15 +33,14 @@ import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.schemes.ColourSchemeProperty; import jalview.schemes.UserColourScheme; +import jalview.structure.CommandListener; import jalview.structure.SelectionSource; +import jalview.structure.StructureSelectionManager; import jalview.structure.VamsasSource; import jalview.viewmodel.AlignmentViewport; -import java.awt.Font; -import java.util.Stack; - public class AlignViewport extends AlignmentViewport implements - AlignViewportI, SelectionSource, VamsasSource + AlignViewportI, SelectionSource, VamsasSource, CommandListener { int startRes; @@ -50,54 +52,16 @@ public class AlignViewport extends AlignmentViewport implements boolean cursorMode = false; - boolean showJVSuffix = true; - - boolean showText = true; - - boolean showColourText = false; - - boolean showBoxes = true; - - boolean wrapAlignment = false; - - boolean renderGaps = true; - - boolean showAnnotation = true; - - boolean upperCasebold = false; - - int charHeight; - - int charWidth; - - int wrappedWidth; - Font font = new Font("SansSerif", Font.PLAIN, 10); boolean validCharWidth = true; - int threshold; - - int increment; - NJTree currentTree = null; - boolean scaleAboveWrapped = true; - - boolean scaleLeftWrapped = true; - - boolean scaleRightWrapped = true; - - boolean showHiddenMarkers = true; - public jalview.bin.JalviewLite applet; boolean MAC = false; - Stack historyList = new Stack(); - - Stack redoList = new Stack(); - private AnnotationColumnChooser annotationColumnSelectionState; public void finalize() @@ -110,9 +74,10 @@ public class AlignViewport extends AlignmentViewport implements public AlignViewport(AlignmentI al, JalviewLite applet) { + super(); calculator = new jalview.workers.AlignCalcManager(); this.applet = applet; - setAlignment(al); + alignment = al; // we always pad gaps this.setPadGaps(true); this.startRes = 0; @@ -175,10 +140,11 @@ public class AlignViewport extends AlignmentViewport implements if (applet != null) { - showJVSuffix = applet.getDefaultParameter("showFullId", showJVSuffix); + setShowJVSuffix(applet.getDefaultParameter("showFullId", + getShowJVSuffix())); - showAnnotation = applet.getDefaultParameter("showAnnotation", - showAnnotation); + setShowAnnotation(applet.getDefaultParameter("showAnnotation", + isShowAnnotation())); showConservation = applet.getDefaultParameter("showConservation", showConservation); @@ -188,15 +154,15 @@ public class AlignViewport extends AlignmentViewport implements showConsensus = applet.getDefaultParameter("showConsensus", showConsensus); - showUnconserved = applet.getDefaultParameter("showUnconserved", - showUnconserved); + setShowUnconserved(applet.getDefaultParameter("showUnconserved", + getShowUnconserved())); String param = applet.getParameter("upperCase"); if (param != null) { if (param.equalsIgnoreCase("bold")) { - upperCasebold = true; + setUpperCasebold(true); } } sortByTree = applet.getDefaultParameter("sortByTree", sortByTree); @@ -272,7 +238,7 @@ public class AlignViewport extends AlignmentViewport implements { return null; } - StringBuffer seqs = new StringBuffer(); + StringBuilder seqs = new StringBuilder(consensus.annotations.length); for (int i = 0; i < consensus.annotations.length; i++) { if (consensus.annotations[i] != null) @@ -368,13 +334,13 @@ public class AlignViewport extends AlignmentViewport implements java.awt.FontMetrics fm = nullFrame.getGraphics().getFontMetrics(font); setCharHeight((int) (heightScale * fm.getHeight())); - charWidth = (int) (widthScale * fm.charWidth('M')); + setCharWidth((int) (widthScale * fm.charWidth('M'))); - if (upperCasebold) + if (isUpperCasebold()) { Font f2 = new Font(f.getName(), Font.BOLD, f.getSize()); fm = nullFrame.getGraphics().getFontMetrics(f2); - charWidth = (int) (widthScale * (fm.stringWidth("MMMMMMMMMMM") / 10)); + setCharWidth((int) (widthScale * (fm.stringWidth("MMMMMMMMMMM") / 10))); } } @@ -383,98 +349,6 @@ public class AlignViewport extends AlignmentViewport implements return font; } - public int getCharWidth() - { - return charWidth; - } - - public void setCharHeight(int h) - { - this.charHeight = h; - } - - public int getCharHeight() - { - return charHeight; - } - - public void setWrappedWidth(int w) - { - this.wrappedWidth = w; - } - - public int getwrappedWidth() - { - return wrappedWidth; - } - - public AlignmentI getAlignment() - { - return alignment; - } - - public void setAlignment(AlignmentI align) - { - this.alignment = align; - } - - public void setWrapAlignment(boolean state) - { - wrapAlignment = state; - } - - public void setShowText(boolean state) - { - showText = state; - } - - public void setRenderGaps(boolean state) - { - renderGaps = state; - } - - public boolean getColourText() - { - return showColourText; - } - - public void setColourText(boolean state) - { - showColourText = state; - } - - public void setShowBoxes(boolean state) - { - showBoxes = state; - } - - public boolean getWrapAlignment() - { - return wrapAlignment; - } - - public boolean getShowText() - { - return showText; - } - - public boolean getShowBoxes() - { - return showBoxes; - } - - public char getGapCharacter() - { - return getAlignment().getGapCharacter(); - } - - public void setGapCharacter(char gap) - { - if (getAlignment() != null) - { - getAlignment().setGapCharacter(gap); - } - } public void resetSeqLimits(int height) { @@ -491,77 +365,6 @@ public class AlignViewport extends AlignmentViewport implements return currentTree; } - public boolean getShowJVSuffix() - { - return showJVSuffix; - } - - public void setShowJVSuffix(boolean b) - { - showJVSuffix = b; - } - - public boolean getShowAnnotation() - { - return showAnnotation; - } - - public void setShowAnnotation(boolean b) - { - showAnnotation = b; - } - - public boolean getScaleAboveWrapped() - { - return scaleAboveWrapped; - } - - public boolean getScaleLeftWrapped() - { - return scaleLeftWrapped; - } - - public boolean getScaleRightWrapped() - { - return scaleRightWrapped; - } - - public void setScaleAboveWrapped(boolean b) - { - scaleAboveWrapped = b; - } - - public void setScaleLeftWrapped(boolean b) - { - scaleLeftWrapped = b; - } - - public void setScaleRightWrapped(boolean b) - { - scaleRightWrapped = b; - } - - public void setIgnoreGapsConsensus(boolean b) - { - ignoreGapsInConsensusCalculation = b; - updateConsensus(null); - if (globalColourScheme != null) - { - globalColourScheme.setThreshold(globalColourScheme.getThreshold(), - ignoreGapsInConsensusCalculation); - - } - } - - public boolean getShowHiddenMarkers() - { - return showHiddenMarkers; - } - - public void setShowHiddenMarkers(boolean show) - { - showHiddenMarkers = show; - } boolean centreColumnLabels; @@ -590,13 +393,25 @@ public class AlignViewport extends AlignmentViewport implements public void sendSelection() { - jalview.structure.StructureSelectionManager - .getStructureSelectionManager(applet).sendSelection( + getStructureSelectionManager().sendSelection( new SequenceGroup(getSelectionGroup()), new ColumnSelection(getColumnSelection()), this); } /** + * Returns an instance of the StructureSelectionManager scoped to this applet + * instance. + * + * @return + */ + @Override + public StructureSelectionManager getStructureSelectionManager() + { + return jalview.structure.StructureSelectionManager + .getStructureSelectionManager(applet); + } + + /** * synthesize a column selection if none exists so it covers the given * selection group. if wholewidth is false, no column selection is made if the * selection group covers the whole alignment width. @@ -659,4 +474,41 @@ public class AlignViewport extends AlignmentViewport implements this.annotationColumnSelectionState = annotationColumnSelectionState; } + @Override + public void mirrorCommand(CommandI command, boolean undo, + StructureSelectionManager ssm, VamsasSource source) + { + // TODO refactor so this can be pulled up to superclass or controller + /* + * Do nothing unless we are a 'complement' of the source. May replace this + * with direct calls not via SSM. + */ + if (source instanceof AlignViewportI + && ((AlignViewportI) source).getCodingComplement() == this) + { + // ok to continue; + } + else + { + return; + } + + CommandI mappedCommand = ssm.mapCommand(command, undo, getAlignment(), + getGapCharacter()); + if (mappedCommand != null) + { + mappedCommand.doCommand(null); + firePropertyChange("alignment", null, getAlignment().getSequences()); + + // ap.scalePanelHolder.repaint(); + // ap.repaint(); + } + } + + @Override + public VamsasSource getVamsasSource() + { + return this; + } + } diff --git a/src/jalview/appletgui/AlignmentPanel.java b/src/jalview/appletgui/AlignmentPanel.java index 7c4882a..c74914f 100644 --- a/src/jalview/appletgui/AlignmentPanel.java +++ b/src/jalview/appletgui/AlignmentPanel.java @@ -20,12 +20,6 @@ */ package jalview.appletgui; -import jalview.api.AlignmentViewPanel; -import jalview.datamodel.AlignmentI; -import jalview.datamodel.SearchResults; -import jalview.datamodel.SequenceI; -import jalview.structure.StructureSelectionManager; - import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; @@ -39,6 +33,14 @@ import java.awt.event.AdjustmentListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; +import jalview.analysis.AnnotationSorter; +import jalview.api.AlignViewportI; +import jalview.api.AlignmentViewPanel; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SearchResults; +import jalview.datamodel.SequenceI; +import jalview.structure.StructureSelectionManager; + public class AlignmentPanel extends Panel implements AdjustmentListener, AlignmentViewPanel { @@ -100,7 +102,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, sequenceHolderPanel.add(annotationPanelHolder, BorderLayout.SOUTH); alabels = new AnnotationLabels(this); - setAnnotationVisible(av.showAnnotation); + setAnnotationVisible(av.isShowAnnotation()); idPanelHolder.add(idPanel, BorderLayout.CENTER); idSpaceFillerPanel1.add(idwidthAdjuster, BorderLayout.CENTER); @@ -153,6 +155,11 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, }); } + @Override + public AlignViewportI getAlignViewport() + { + return av; + } public SequenceRenderer getSequenceRenderer() { return seqPanel.seqCanvas.sr; @@ -190,8 +197,9 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, idPanel.idCanvas.image = null; FontMetrics fm = getFontMetrics(av.getFont()); - scalePanel.setSize(new Dimension(10, av.charHeight + fm.getDescent())); - idwidthAdjuster.setSize(new Dimension(10, av.charHeight + scalePanel.setSize(new Dimension(10, av.getCharHeight() + + fm.getDescent())); + idwidthAdjuster.setSize(new Dimension(10, av.getCharHeight() + fm.getDescent())); av.updateSequenceIdColours(); annotationPanel.image = null; @@ -375,7 +383,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, { start = ostart; } - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { /* * int spos=av.getStartRes(),sqpos=av.getStartSeq(); if ((startv = @@ -449,7 +457,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, public void setAnnotationVisible(boolean b) { - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { annotationSpaceFillerHolder.setVisible(b); annotationPanelHolder.setVisible(b); @@ -473,7 +481,8 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, // this is called after loading new annotation onto alignment if (alignFrame.getSize().height == 0) { - System.out.println("NEEDS FIXING"); + System.out + .println("adjustAnnotationHeight frame size zero NEEDS FIXING"); } fontChanged(); validateAnnotationDimensions(true); @@ -566,7 +575,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, annotationPanelHolder.setVisible(false); annotationSpaceFillerHolder.setVisible(false); } - else if (av.showAnnotation) + else if (av.isShowAnnotation()) { annotationPanelHolder.setVisible(true); annotationSpaceFillerHolder.setVisible(true); @@ -648,8 +657,8 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, } ; - hextent = seqPanel.seqCanvas.getSize().width / av.charWidth; - vextent = seqPanel.seqCanvas.getSize().height / av.charHeight; + hextent = seqPanel.seqCanvas.getSize().width / av.getCharWidth(); + vextent = seqPanel.seqCanvas.getSize().height / av.getCharHeight(); if (hextent > width) { @@ -694,7 +703,8 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, av.setEndSeq(endSeq); av.setStartRes(x); - av.setEndRes((x + (seqPanel.seqCanvas.getSize().width / av.charWidth)) - 1); + av.setEndRes((x + (seqPanel.seqCanvas.getSize().width / av + .getCharWidth())) - 1); hscroll.setValues(x, hextent, 0, width); vscroll.setValues(y, vextent, 0, height); @@ -776,7 +786,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, seqPanel.seqCanvas.fastPaint(scrollX, scrollY); scalePanel.repaint(); - if (av.getShowAnnotation()) + if (av.isShowAnnotation()) { annotationPanel.fastPaint(av.getStartRes() - oldX); } @@ -792,8 +802,15 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, av.endSeq); } + /** + * Repaint the alignment and annotations, and, optionally, any overview window + */ public void paintAlignment(boolean updateOverview) { + final AnnotationSorter sorter = new AnnotationSorter(getAlignment(), + av.isShowAutocalculatedAbove()); + sorter.sort(getAlignment().getAlignmentAnnotation(), + av.getSortAnnotationsBy()); repaint(); if (updateOverview) @@ -847,9 +864,9 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, seqPanel.seqCanvas.repaint(); idPanel.idCanvas.repaint(); - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { - if (av.showAnnotation) + if (av.isShowAnnotation()) { alabels.repaint(); annotationPanel.repaint(); diff --git a/src/jalview/appletgui/AnnotationLabels.java b/src/jalview/appletgui/AnnotationLabels.java index f288188..67faf11 100755 --- a/src/jalview/appletgui/AnnotationLabels.java +++ b/src/jalview/appletgui/AnnotationLabels.java @@ -20,13 +20,6 @@ */ package jalview.appletgui; -import jalview.datamodel.AlignmentAnnotation; -import jalview.datamodel.Annotation; -import jalview.datamodel.SequenceGroup; -import jalview.datamodel.SequenceI; -import jalview.util.MessageManager; -import jalview.util.ParseHtmlBodyAndLinks; - import java.awt.Checkbox; import java.awt.CheckboxMenuItem; import java.awt.Color; @@ -48,8 +41,17 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.Arrays; +import java.util.Collections; import java.util.Vector; +import jalview.analysis.AlignmentUtils; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.Annotation; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; +import jalview.util.MessageManager; +import jalview.util.ParseHtmlBodyAndLinks; + public class AnnotationLabels extends Panel implements ActionListener, MouseListener, MouseMotionListener { @@ -211,6 +213,14 @@ public class AnnotationLabels extends Panel implements ActionListener, } } + refresh(); + } + + /** + * Adjust size and repaint + */ + protected void refresh() + { ap.annotationPanel.adjustPanelHeight(); setSize(getSize().width, ap.annotationPanel.getSize().height); ap.validate(); @@ -311,8 +321,8 @@ public class AnnotationLabels extends Panel implements ActionListener, .getSize(), f = ap.seqPanelHolder.getSize(); int dif = evt.getY() - oldY; - dif /= ap.av.charHeight; - dif *= ap.av.charHeight; + dif /= ap.av.getCharHeight(); + dif *= ap.av.getCharHeight(); if ((d.height - dif) > 20 && (f.height + dif) > 20) { @@ -461,6 +471,32 @@ public class AnnotationLabels extends Panel implements ActionListener, item = new MenuItem(HIDE); item.addActionListener(this); popup.add(item); + + /* + * Hide all

    + *
  • a new Insert positions to the right of the last , or
  • + *
  • a new Delete gaps which is positions to the left of the last + * delete.
  • + *
+ */ + boolean contiguous = (action == Action.INSERT_GAP && e.position == lastEdit.position + + lastEdit.number) + || (action == Action.DELETE_GAP && e.position + e.number == lastEdit.position); + if (contiguous) + { + /* + * We are just expanding the range of the last edit. For delete gap, also + * moving the start position left. + */ + lastEdit.number += e.number; + lastEdit.seqs = e.seqs; + if (action == Action.DELETE_GAP) + { + lastEdit.position--; + } + return true; + } + return false; } /** @@ -209,7 +337,32 @@ public class EditCommand implements CommandI edit.fullAlignmentHeight = true; } - edits.add(edit); + addEdit(edit); + + if (performEdit) + { + performEdit(edit, views); + } + } + + /** + * Overloaded method that accepts an Edit object with additional parameters. + * + * @param edit + * @param al + * @param performEdit + * @param views + */ + final public void appendEdit(Edit edit, AlignmentI al, + boolean performEdit, AlignmentI[] views) + { + if (al.getHeight() == edit.seqs.length) + { + edit.al = al; + edit.fullAlignmentHeight = true; + } + + addEdit(edit); if (performEdit) { @@ -223,7 +376,7 @@ public class EditCommand implements CommandI * @param commandIndex * @param views */ - final void performEdit(int commandIndex, AlignmentI[] views) + public final void performEdit(int commandIndex, AlignmentI[] views) { ListIterator iterator = edits.listIterator(commandIndex); while (iterator.hasNext()) @@ -239,7 +392,7 @@ public class EditCommand implements CommandI * @param edit * @param views */ - protected void performEdit(Edit edit, AlignmentI[] views) + protected static void performEdit(Edit edit, AlignmentI[] views) { switch (edit.command) { @@ -316,13 +469,13 @@ public class EditCommand implements CommandI * * @param command */ - final private void insertGap(Edit command) + final private static void insertGap(Edit command) { for (int s = 0; s < command.seqs.length; s++) { - command.seqs[s].insertCharAt(command.position, command.number, - command.gapChar); + command.seqs[s].insertCharAt(command.position, + command.number, command.gapChar); // System.out.println("pos: "+command.position+" number: "+command.number); } @@ -348,7 +501,7 @@ public class EditCommand implements CommandI * * @param command */ - final private void deleteGap(Edit command) + final static private void deleteGap(Edit command) { for (int s = 0; s < command.seqs.length; s++) { @@ -366,7 +519,7 @@ public class EditCommand implements CommandI * @param command * @param views */ - void cut(Edit command, AlignmentI[] views) + static void cut(Edit command, AlignmentI[] views) { boolean seqDeleted = false; command.string = new char[command.seqs.length][]; @@ -430,7 +583,7 @@ public class EditCommand implements CommandI * @param command * @param views */ - void paste(Edit command, AlignmentI[] views) + static void paste(Edit command, AlignmentI[] views) { StringBuffer tmp; boolean newDSNeeded; @@ -446,7 +599,7 @@ public class EditCommand implements CommandI if (command.seqs[i].getLength() < 1) { // ie this sequence was deleted, we need to - // read it to the alignment + // readd it to the alignment if (command.alIndex[i] < command.al.getHeight()) { List sequences; @@ -548,7 +701,7 @@ public class EditCommand implements CommandI command.string = null; } - void replace(Edit command) + static void replace(Edit command) { StringBuffer tmp; String oldstring; @@ -625,7 +778,7 @@ public class EditCommand implements CommandI } } - final void adjustAnnotations(Edit command, boolean insert, + final static void adjustAnnotations(Edit command, boolean insert, boolean modifyVisibility, AlignmentI[] views) { AlignmentAnnotation[] annotations = null; @@ -949,7 +1102,7 @@ public class EditCommand implements CommandI } } - final void adjustFeatures(Edit command, int index, int i, int j, + final static void adjustFeatures(Edit command, int index, int i, int j, boolean insert) { SequenceI seq = command.seqs[index]; @@ -1027,7 +1180,112 @@ public class EditCommand implements CommandI } - class Edit + /** + * Returns the list of edit commands wrapped by this object. + * + * @return + */ + public List getEdits() + { + return this.edits; + } + + /** + * Returns a map whose keys are the dataset sequences, and values their + * aligned sequences before the command edit list was applied. The aligned + * sequences are copies, which may be updated without affecting the originals. + * + * The command holds references to the aligned sequences (after editing). If + * the command is an 'undo',then the prior state is simply the aligned state. + * Otherwise, we have to derive the prior state by working backwards through + * the edit list to infer the aligned sequences before editing. + * + * Note: an alternative solution would be to cache the 'before' state of each + * edit, but this would be expensive in space in the common case that the + * original is never needed (edits are not mirrored). + * + * @return + * @throws IllegalStateException + * on detecting an edit command of a type that can't be unwound + */ + public Map priorState(boolean forUndo) + { + Map result = new HashMap(); + if (getEdits() == null) + { + return result; + } + if (forUndo) + { + for (Edit e : getEdits()) + { + for (SequenceI seq : e.getSequences()) + { + SequenceI ds = seq.getDatasetSequence(); + SequenceI preEdit = result.get(ds); + if (preEdit == null) + { + preEdit = new Sequence("", seq.getSequenceAsString()); + preEdit.setDatasetSequence(ds); + result.put(ds, preEdit); + } + } + } + return result; + } + + /* + * Work backwards through the edit list, deriving the sequences before each + * was applied. The final result is the sequence set before any edits. + */ + Iterator edits = new ReverseListIterator(getEdits()); + while (edits.hasNext()) + { + Edit oldEdit = edits.next(); + Action action = oldEdit.getAction(); + int position = oldEdit.getPosition(); + int number = oldEdit.getNumber(); + final char gap = oldEdit.getGapCharacter(); + for (SequenceI seq : oldEdit.getSequences()) + { + SequenceI ds = seq.getDatasetSequence(); + SequenceI preEdit = result.get(ds); + if (preEdit == null) + { + preEdit = new Sequence("", seq.getSequenceAsString()); + preEdit.setDatasetSequence(ds); + result.put(ds, preEdit); + } + /* + * 'Undo' this edit action on the sequence (updating the value in the + * map). + */ + if (ds != null) + { + if (action == Action.DELETE_GAP) + { + preEdit.setSequence(new String(StringUtils.insertCharAt( + preEdit.getSequence(), position, + number, gap))); + } + else if (action == Action.INSERT_GAP) + { + preEdit.setSequence(new String(StringUtils.deleteChars( + preEdit.getSequence(), position, position + number))); + } + else + { + System.err.println("Can't undo edit action " + action); + // throw new IllegalStateException("Can't undo edit action " + + // action); + } + } + } + } + return result; + } + + public class Edit { public SequenceI[] oldds; @@ -1053,7 +1311,7 @@ public class EditCommand implements CommandI char gapChar; - Edit(Action command, SequenceI[] seqs, int position, int number, + public Edit(Action command, SequenceI[] seqs, int position, int number, char gapChar) { this.command = command; @@ -1099,5 +1357,49 @@ public class EditCommand implements CommandI fullAlignmentHeight = (al.getHeight() == seqs.length); } + + public SequenceI[] getSequences() + { + return seqs; + } + + public int getPosition() + { + return position; + } + + public Action getAction() + { + return command; + } + + public int getNumber() + { + return number; + } + + public char getGapCharacter() + { + return gapChar; + } + } + + /** + * Returns an iterator over the list of edit commands which traverses the list + * either forwards or backwards. + * + * @param forwards + * @return + */ + public Iterator getEditIterator(boolean forwards) + { + if (forwards) + { + return getEdits().iterator(); + } + else + { + return new ReverseListIterator(getEdits()); + } } } diff --git a/src/jalview/commands/OrderCommand.java b/src/jalview/commands/OrderCommand.java index bc72406..5758e19 100644 --- a/src/jalview/commands/OrderCommand.java +++ b/src/jalview/commands/OrderCommand.java @@ -20,19 +20,46 @@ */ package jalview.commands; -import jalview.analysis.*; -import jalview.datamodel.*; +import jalview.analysis.AlignmentSorter; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SequenceI; +/** + * An undoable command to reorder the sequences in an alignment. + * + * @author gmcarstairs + * + */ public class OrderCommand implements CommandI { String description; + /* + * The sequence order before sorting (target order for an undo) + */ SequenceI[] seqs; + /* + * The sequence order specified by this command + */ SequenceI[] seqs2; + /* + * The alignment the command acts on + */ AlignmentI al; + /** + * Constructor given the 'undo' sequence order, and the (already) sorted + * alignment. + * + * @param description + * a text label for the 'undo' menu option + * @param seqs + * the sequence order for undo + * @param al + * the alignment as ordered by this command + */ public OrderCommand(String description, SequenceI[] seqs, AlignmentI al) { this.description = description; @@ -61,4 +88,15 @@ public class OrderCommand implements CommandI { AlignmentSorter.setOrder(al, seqs); } + + /** + * Returns the sequence order used to sort, or before sorting if undo=true. + * + * @param undo + * @return + */ + public SequenceI[] getSequenceOrder(boolean undo) + { + return undo ? seqs : seqs2; + } } diff --git a/src/jalview/controller/AlignViewController.java b/src/jalview/controller/AlignViewController.java index 2d74590..972b6ab 100644 --- a/src/jalview/controller/AlignViewController.java +++ b/src/jalview/controller/AlignViewController.java @@ -179,13 +179,7 @@ public class AlignViewController implements AlignViewControllerI int tfeat = 0; if (sq != null) { - SequenceI dsq = sq.getDatasetSequence(); - while (dsq.getDatasetSequence() != null) - { - dsq = dsq.getDatasetSequence(); - } - ; - SequenceFeature[] sf = dsq.getSequenceFeatures(); + SequenceFeature[] sf = sq.getSequenceFeatures(); if (sf != null) { int ist = sq.findIndex(sq.getStart()); diff --git a/src/jalview/datamodel/AlignedCodon.java b/src/jalview/datamodel/AlignedCodon.java new file mode 100644 index 0000000..0daa3fb --- /dev/null +++ b/src/jalview/datamodel/AlignedCodon.java @@ -0,0 +1,86 @@ +package jalview.datamodel; + +/** + * Holds the aligned column positions (base 0) for one codon in a nucleotide + * sequence, and (optionally) its peptide translation. The object is immutable + * once created. + * + * Example: in "G-AT-C-GA" the aligned codons are (0, 2, 3) and (5, 7, 8). + * + * @author gmcarstairs + * + */ +public final class AlignedCodon +{ + public final int pos1; + + public final int pos2; + + public final int pos3; + + public final String product; + + public AlignedCodon(int i, int j, int k) + { + this(i, j, k, null); + } + + public AlignedCodon(int i, int j, int k, String prod) + { + pos1 = i; + pos2 = j; + pos3 = k; + product = prod; + } + + /** + * Returns the column position for the given base (1, 2, 3). + * + * @param base + * @return + * @throws IllegalArgumentException + * if an argument value other than 1, 2 or 3 is supplied + */ + public int getBaseColumn(int base) + { + if (base < 1 || base > 3) + { + throw new IllegalArgumentException(Integer.toString(base)); + } + return base == 1 ? pos1 : (base == 2 ? pos2 : pos3); + } + + /** + * Two aligned codons are equal if all their base positions are the same. We + * don't care about the protein product. This test is required for correct + * alignment of translated gapped dna alignments (the same codon positions in + * different sequences occupy the same column in the translated alignment). + */ + @Override + public boolean equals(Object o) + { + /* + * Equality with null value required for consistency with + * Dna.compareCodonPos + */ + if (o == null) + { + return true; + } + if (!(o instanceof AlignedCodon)) + { + return false; + } + AlignedCodon ac = (AlignedCodon) o; + return (pos1 == ac.pos1 && pos2 == ac.pos2 && pos3 == ac.pos3); + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("[").append(pos1).append(", ").append(pos2).append(", ") + .append(pos3).append("]"); + return sb.toString(); + } +} diff --git a/src/jalview/datamodel/AlignedCodonFrame.java b/src/jalview/datamodel/AlignedCodonFrame.java index 55df1af..1f5d827 100644 --- a/src/jalview/datamodel/AlignedCodonFrame.java +++ b/src/jalview/datamodel/AlignedCodonFrame.java @@ -20,134 +20,37 @@ */ package jalview.datamodel; -import java.util.Enumeration; -import java.util.Vector; - import jalview.util.MapList; +import jalview.util.MappingUtils; /** * Stores mapping between the columns of a protein alignment and a DNA alignment * and a list of individual codon to amino acid mappings between sequences. */ - public class AlignedCodonFrame { - /** - * array of nucleotide positions for aligned codons at column of aligned - * proteins. - */ - public int[][] codons = null; - - /** - * width of protein sequence alignement implicit assertion that codons.length - * >= aaWidth - */ - public int aaWidth = 0; - /** - * initialise codon frame with a nominal alignment width - * - * @param aWidth + /* + * tied array of na Sequence objects. */ - public AlignedCodonFrame(int aWidth) - { - if (aWidth <= 0) - { - codons = null; - return; - } - codons = new int[aWidth][]; - for (int res = 0; res < aWidth; res++) - codons[res] = null; - } + private SequenceI[] dnaSeqs = null; - /** - * ensure that codons array is at least as wide as aslen residues - * - * @param aslen - * @return (possibly newly expanded) codon array + /* + * tied array of Mappings to protein sequence Objects and SequenceI[] + * aaSeqs=null; MapLists where each maps from the corresponding dnaSeqs + * element to corresponding aaSeqs element */ - public int[][] checkCodonFrameWidth(int aslen) - { - if (codons.length <= aslen + 1) - { - // probably never have to do this ? - int[][] c = new int[codons.length + 10][]; - for (int i = 0; i < codons.length; i++) - { - c[i] = codons[i]; - codons[i] = null; - } - codons = c; - } - return codons; - } + private Mapping[] dnaToProt = null; /** - * @return width of aligned translated amino acid residues + * Constructor */ - public int getaaWidth() + public AlignedCodonFrame() { - return aaWidth; } /** - * TODO: not an ideal solution - we reference the aligned amino acid sequences - * in order to make insertions on them Better would be dnaAlignment and - * aaAlignment reference.... - */ - Vector a_aaSeqs = new Vector(); - - /** - * increase aaWidth by one and insert a new aligned codon position space at - * aspos. - * - * @param aspos - */ - public void insertAAGap(int aspos, char gapCharacter) - { - // this aa appears before the aligned codons at aspos - so shift them in - // each pair of mapped sequences - aaWidth++; - if (a_aaSeqs != null) - { - // we actually have to modify the aligned sequences here, so use the - // a_aaSeqs vector - Enumeration sq = a_aaSeqs.elements(); - while (sq.hasMoreElements()) - { - ((SequenceI) sq.nextElement()).insertCharAt(aspos, gapCharacter); - } - } - checkCodonFrameWidth(aspos); - if (aspos < aaWidth) - { - aaWidth++; - System.arraycopy(codons, aspos, codons, aspos + 1, codons.length - - aspos - 1); - codons[aspos] = null; // clear so new codon position can be marked. - } - } - - public void setAaWidth(int aapos) - { - aaWidth = aapos; - } - - /** - * tied array of na Sequence objects. - */ - SequenceI[] dnaSeqs = null; - - /** - * tied array of Mappings to protein sequence Objects and SequenceI[] - * aaSeqs=null; MapLists where eac maps from the corresponding dnaSeqs element - * to corresponding aaSeqs element - */ - Mapping[] dnaToProt = null; - - /** - * add a mapping between the dataset sequences for the associated dna and + * Adds a mapping between the dataset sequences for the associated dna and * protein sequence objects * * @param dnaseq @@ -179,7 +82,6 @@ public class AlignedCodonFrame // aaseq.transferAnnotation(dnaseq, new Mapping(map.getInverse())); mp.to = (aaseq.getDatasetSequence() == null) ? aaseq : aaseq .getDatasetSequence(); - a_aaSeqs.addElement(aaseq); dnaToProt[nlen] = mp; } @@ -191,7 +93,9 @@ public class AlignedCodonFrame public SequenceI[] getAaSeqs() { if (dnaToProt == null) + { return null; + } SequenceI[] sqs = new SequenceI[dnaToProt.length]; for (int sz = 0; sz < dnaToProt.length; sz++) { @@ -203,7 +107,9 @@ public class AlignedCodonFrame public MapList[] getdnaToProt() { if (dnaToProt == null) + { return null; + } MapList[] sqs = new MapList[dnaToProt.length]; for (int sz = 0; sz < dnaToProt.length; sz++) { @@ -218,9 +124,37 @@ public class AlignedCodonFrame } /** + * Returns the first mapping found which is to or from the given sequence, or + * null. + * + * @param seq + * @return + */ + public Mapping getMappingForSequence(SequenceI seq) + { + if (dnaSeqs == null) + { + return null; + } + SequenceI seqDs = seq.getDatasetSequence(); + seqDs = seqDs != null ? seqDs : seq; + + for (int ds = 0; ds < dnaSeqs.length; ds++) + { + if (dnaSeqs[ds] == seqDs || dnaToProt[ds].to == seqDs) + { + return dnaToProt[ds]; + } + } + return null; + } + + /** + * Return the corresponding aligned or dataset aa sequence for given dna + * sequence, null if not found. * * @param sequenceRef - * @return null or corresponding aaSeq entry for dnaSeq entry + * @return */ public SequenceI getAaForDnaSeq(SequenceI dnaSeqRef) { @@ -232,7 +166,9 @@ public class AlignedCodonFrame for (int ds = 0; ds < dnaSeqs.length; ds++) { if (dnaSeqs[ds] == dnaSeqRef || dnaSeqs[ds] == dnads) + { return dnaToProt[ds].to; + } } return null; } @@ -252,7 +188,9 @@ public class AlignedCodonFrame for (int as = 0; as < dnaToProt.length; as++) { if (dnaToProt[as].to == aaSeqRef || dnaToProt[as].to == aads) + { return dnaSeqs[as]; + } } return null; } @@ -319,4 +257,170 @@ public class AlignedCodonFrame } } } + + /** + * Returns the DNA codon positions (base 1) for the given position (base 1) in + * a mapped protein sequence, or null if no mapping is found. + * + * Intended for use in aligning cDNA to match aligned protein. Only the first + * mapping found is returned, so not suitable for use if multiple protein + * sequences are mapped to the same cDNA (but aligning cDNA as protein is + * ill-defined for this case anyway). + * + * @param seq + * the DNA dataset sequence + * @param aaPos + * residue position (base 1) in a protein sequence + * @return + */ + public int[] getDnaPosition(SequenceI seq, int aaPos) + { + /* + * Adapted from markMappedRegion(). + */ + MapList ml = null; + for (int i = 0; i < dnaToProt.length; i++) + { + if (dnaSeqs[i] == seq) + { + ml = getdnaToProt()[i]; + break; + } + } + return ml == null ? null : ml.locateInFrom(aaPos, aaPos); + } + + /** + * Convenience method to return the first aligned sequence in the given + * alignment whose dataset has a mapping with the given dataset sequence. + * + * @param seq + * + * @param al + * @return + */ + public SequenceI findAlignedSequence(SequenceI seq, AlignmentI al) + { + /* + * Search mapped protein ('to') sequences first. + */ + if (this.dnaToProt != null) + { + for (int i = 0; i < dnaToProt.length; i++) + { + if (this.dnaSeqs[i] == seq) + { + for (SequenceI sourceAligned : al.getSequences()) + { + if (this.dnaToProt[i].to == sourceAligned.getDatasetSequence()) + { + return sourceAligned; + } + } + } + } + } + + /* + * Then try mapped dna sequences. + */ + if (this.dnaToProt != null) + { + for (int i = 0; i < dnaToProt.length; i++) + { + if (this.dnaToProt[i].to == seq) + { + for (SequenceI sourceAligned : al.getSequences()) + { + if (this.dnaSeqs[i] == sourceAligned.getDatasetSequence()) + { + return sourceAligned; + } + } + } + } + } + + return null; + } + + /** + * Returns the region in the 'mappedFrom' sequence's dataset that is mapped to + * position 'pos' (base 1) in the 'mappedTo' sequence's dataset. The region is + * a set of start/end position pairs. + * + * @param mappedFrom + * @param mappedTo + * @param pos + * @return + */ + public int[] getMappedRegion(SequenceI mappedFrom, SequenceI mappedTo, + int pos) + { + SequenceI targetDs = mappedFrom.getDatasetSequence() == null ? mappedFrom + : mappedFrom.getDatasetSequence(); + SequenceI sourceDs = mappedTo.getDatasetSequence() == null ? mappedTo + : mappedTo.getDatasetSequence(); + if (targetDs == null || sourceDs == null || dnaToProt == null) + { + return null; + } + for (int mi = 0; mi < dnaToProt.length; mi++) + { + if (dnaSeqs[mi] == targetDs && dnaToProt[mi].to == sourceDs) + { + int[] codon = dnaToProt[mi].map.locateInFrom(pos, pos); + if (codon != null) { + return codon; + } + } + } + return null; + } + + /** + * Returns the DNA codon for the given position (base 1) in a mapped protein + * sequence, or null if no mapping is found. + * + * @param protein + * the peptide dataset sequence + * @param aaPos + * residue position (base 1) in the peptide sequence + * @return + */ + public char[] getMappedCodon(SequenceI protein, int aaPos) + { + if (dnaToProt == null) + { + return null; + } + MapList ml = null; + char[] dnaSeq = null; + for (int i = 0; i < dnaToProt.length; i++) + { + if (dnaToProt[i].to == protein) + { + ml = getdnaToProt()[i]; + dnaSeq = dnaSeqs[i].getSequence(); + break; + } + } + if (ml == null) + { + return null; + } + int[] codonPos = ml.locateInFrom(aaPos, aaPos); + if (codonPos == null) + { + return null; + } + + /* + * Read off the mapped nucleotides (converting to position base 0) + */ + codonPos = MappingUtils.flattenRanges(codonPos); + return new char[] + { dnaSeq[codonPos[0] - 1], dnaSeq[codonPos[1] - 1], + dnaSeq[codonPos[2] - 1] }; + } } diff --git a/src/jalview/datamodel/Alignment.java b/src/jalview/datamodel/Alignment.java index ace4f30..482df7f 100755 --- a/src/jalview/datamodel/Alignment.java +++ b/src/jalview/datamodel/Alignment.java @@ -20,13 +20,18 @@ */ package jalview.datamodel; +import jalview.analysis.AlignmentUtils; +import jalview.io.FastaFile; import jalview.util.MessageManager; import java.util.ArrayList; import java.util.Enumeration; +import java.util.HashSet; import java.util.Hashtable; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.Vector; /** @@ -62,6 +67,8 @@ public class Alignment implements AlignmentI public Hashtable alignmentProperties; + private Set codonFrameList = new LinkedHashSet(); + private void initAlignment(SequenceI[] seqs) { int i = 0; @@ -86,6 +93,27 @@ public class Alignment implements AlignmentI } /** + * Make a 'copy' alignment - sequences have new copies of features and + * annotations, but share the original dataset sequences. + */ + public Alignment(AlignmentI al) + { + SequenceI[] seqs = al.getSequencesArray(); + for (int i = 0; i < seqs.length; i++) + { + seqs[i] = new Sequence(seqs[i]); + } + + /* + * Share the same dataset sequence mappings (if any). TODO: find a better + * place for these to live (alignment dataset?). + */ + this.codonFrameList = ((Alignment) al).codonFrameList; + + initAlignment(seqs); + } + + /** * Make an alignment from an array of Sequences. * * @param sequences @@ -123,11 +151,6 @@ public class Alignment implements AlignmentI // this(compactAlignment.refCigars); } - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ @Override public List getSequences() { @@ -157,6 +180,17 @@ public class Alignment implements AlignmentI } /** + * Returns a map of lists of sequences keyed by sequence name. + * + * @return + */ + @Override + public Map> getSequencesByName() + { + return AlignmentUtils.getSequencesByName(this); + } + + /** * DOCUMENT ME! * * @param i @@ -226,10 +260,9 @@ public class Alignment implements AlignmentI @Override public void setSequenceAt(int i, SequenceI snew) { - SequenceI oldseq = getSequenceAt(i); - deleteSequence(i); synchronized (sequences) { + deleteSequence(i); sequences.set(i, snew); } } @@ -298,8 +331,8 @@ public class Alignment implements AlignmentI synchronized (sequences) { sequences.remove(i); + hiddenSequences.adjustHeightSequenceDeleted(i); } - hiddenSequences.adjustHeightSequenceDeleted(i); } } @@ -343,14 +376,14 @@ public class Alignment implements AlignmentI for (int i = 0; i < gSize; i++) { SequenceGroup sg = groups.get(i); - if (sg == null || sg.getSequences(null) == null) + if (sg == null || sg.getSequences() == null) { this.deleteGroup(sg); gSize--; continue; } - if (sg.getSequences(null).contains(s)) + if (sg.getSequences().contains(s)) { temp.add(sg); } @@ -720,6 +753,28 @@ public class Alignment implements AlignmentI return true; } + /** + * Delete all annotations, including auto-calculated if the flag is set true. + * Returns true if at least one annotation was deleted, else false. + * + * @param includingAutoCalculated + * @return + */ + @Override + public boolean deleteAllAnnotations(boolean includingAutoCalculated) + { + boolean result = false; + for (AlignmentAnnotation alan : getAlignmentAnnotation()) + { + if (!alan.autoCalculated || includingAutoCalculated) + { + deleteAnnotation(alan); + result = true; + } + } + return result; + } + /* * (non-Javadoc) * @@ -1205,8 +1260,6 @@ public class Alignment implements AlignmentI return alignmentProperties; } - AlignedCodonFrame[] codonFrameList = null; - /* * (non-Javadoc) * @@ -1217,31 +1270,10 @@ public class Alignment implements AlignmentI @Override public void addCodonFrame(AlignedCodonFrame codons) { - if (codons == null) + if (codons != null) { - return; - } - if (codonFrameList == null) - { - codonFrameList = new AlignedCodonFrame[] - { codons }; - return; + codonFrameList.add(codons); } - AlignedCodonFrame[] t = new AlignedCodonFrame[codonFrameList.length + 1]; - System.arraycopy(codonFrameList, 0, t, 0, codonFrameList.length); - t[codonFrameList.length] = codons; - codonFrameList = t; - } - - /* - * (non-Javadoc) - * - * @see jalview.datamodel.AlignmentI#getCodonFrame(int) - */ - @Override - public AlignedCodonFrame getCodonFrame(int index) - { - return codonFrameList[index]; } /* @@ -1251,36 +1283,42 @@ public class Alignment implements AlignmentI * jalview.datamodel.AlignmentI#getCodonFrame(jalview.datamodel.SequenceI) */ @Override - public AlignedCodonFrame[] getCodonFrame(SequenceI seq) + public List getCodonFrame(SequenceI seq) { - if (seq == null || codonFrameList == null) + if (seq == null) { return null; } - Vector cframes = new Vector(); - for (int f = 0; f < codonFrameList.length; f++) + List cframes = new ArrayList(); + for (AlignedCodonFrame acf : codonFrameList) { - if (codonFrameList[f].involvesSequence(seq)) + if (acf.involvesSequence(seq)) { - cframes.addElement(codonFrameList[f]); + cframes.add(acf); } } - if (cframes.size() == 0) - { - return null; - } - AlignedCodonFrame[] cfr = new AlignedCodonFrame[cframes.size()]; - cframes.copyInto(cfr); - return cfr; + return cframes; } - /* - * (non-Javadoc) + /** + * Sets the codon frame mappings (replacing any existing mappings). + * + * @see jalview.datamodel.AlignmentI#setCodonFrames() + */ + @Override + public void setCodonFrames(Set acfs) + { + this.codonFrameList = acfs; + } + + /** + * Returns the set of codon frame mappings. Any changes to the returned set + * will affect the alignment. * * @see jalview.datamodel.AlignmentI#getCodonFrames() */ @Override - public AlignedCodonFrame[] getCodonFrames() + public Set getCodonFrames() { return codonFrameList; } @@ -1298,26 +1336,7 @@ public class Alignment implements AlignmentI { return false; } - boolean removed = false; - int i = 0, iSize = codonFrameList.length; - while (i < iSize) - { - if (codonFrameList[i] == codons) - { - removed = true; - if (i + 1 < iSize) - { - System.arraycopy(codonFrameList, i + 1, codonFrameList, i, iSize - - i - 1); - } - iSize--; - } - else - { - i++; - } - } - return removed; + return codonFrameList.remove(codons); } @Override @@ -1362,11 +1381,9 @@ public class Alignment implements AlignmentI { addAnnotation(alan[a]); } - AlignedCodonFrame[] acod = toappend.getCodonFrames(); - for (int a = 0; acod != null && a < acod.length; a++) - { - this.addCodonFrame(acod[a]); - } + + this.codonFrameList.addAll(toappend.getCodonFrames()); + List sg = toappend.getGroups(); if (sg != null) { @@ -1627,4 +1644,91 @@ public class Alignment implements AlignmentI { return dataset; } + + /** + * Align this alignment like the given (mapped) one. + */ + @Override + public int alignAs(AlignmentI al) + { + /* + * Currently retains unmapped gaps (in introns), regaps mapped regions + * (exons) + */ + return alignAs(al, false, true); + } + + /** + * Align this alignment 'the same as' the given one. Mapped sequences only are + * realigned. If both of the same type (nucleotide/protein) then align both + * identically. If this is nucleotide and the other is protein, make 3 gaps + * for each gap in the protein sequences. If this is protein and the other is + * nucleotide, insert a gap for each 3 gaps (or part thereof) between + * nucleotide bases. Does nothing if alignment of protein from cDNA is + * requested (not yet implemented). + * + * Parameters control whether gaps in exon (mapped) and intron (unmapped) + * regions are preserved. Gaps that connect introns to exons are treated + * conservatively, i.e. only preserved if both intron and exon gaps are + * preserved. + * + * @param al + * @param preserveMappedGaps + * if true, gaps within and between mapped codons are preserved + * @param preserveUnmappedGaps + * if true, gaps within and between unmapped codons are preserved + */ +// @Override + public int alignAs(AlignmentI al, boolean preserveMappedGaps, + boolean preserveUnmappedGaps) + { + // TODO should this method signature be the one in the interface? + int count = 0; + boolean thisIsNucleotide = this.isNucleotide(); + boolean thatIsProtein = !al.isNucleotide(); + if (!thatIsProtein && !thisIsNucleotide) + { + return AlignmentUtils.alignProteinAsDna(this, al); + } + + char thisGapChar = this.getGapCharacter(); + String gap = thisIsNucleotide && thatIsProtein ? String + .valueOf(new char[] + { thisGapChar, thisGapChar, thisGapChar }) : String + .valueOf(thisGapChar); + + /* + * Get mappings from 'that' alignment's sequences to this. + */ + for (SequenceI alignTo : getSequences()) + { + count += AlignmentUtils.alignSequenceAs(alignTo, al, gap, preserveMappedGaps, + preserveUnmappedGaps) ? 1 : 0; + } + return count; + } + + /** + * Returns the alignment in Fasta format. Behaviour of this method is not + * guaranteed between versions. + */ + @Override + public String toString() + { + return new FastaFile().print(getSequencesArray()); + } + + /** + * Returns the set of distinct sequence names. No ordering is guaranteed. + */ + @Override + public Set getSequenceNames() + { + Set names = new HashSet(); + for (SequenceI seq : getSequences()) + { + names.add(seq.getName()); + } + return names; + } } diff --git a/src/jalview/datamodel/AlignmentAnnotation.java b/src/jalview/datamodel/AlignmentAnnotation.java index 09d9ee0..1bbe81e 100755 --- a/src/jalview/datamodel/AlignmentAnnotation.java +++ b/src/jalview/datamodel/AlignmentAnnotation.java @@ -27,9 +27,8 @@ import jalview.analysis.WUSSParseException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Enumeration; import java.util.HashMap; -import java.util.Hashtable; +import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; @@ -41,6 +40,15 @@ import java.util.Map.Entry; */ public class AlignmentAnnotation { + /* + * Identifers for different types of profile data + */ + public static final int SEQUENCE_PROFILE = 0; + + public static final int STRUCTURE_PROFILE = 1; + + public static final int CDNA_PROFILE = 2; + /** * If true, this annotations is calculated every edit, eg consensus, quality * or conservation graphs @@ -155,7 +163,7 @@ public class AlignmentAnnotation /** * map of positions in the associated annotation */ - public java.util.Hashtable sequenceMapping; + private Map sequenceMapping; /** DOCUMENT ME!! */ public float graphMin; @@ -499,6 +507,7 @@ public class AlignmentAnnotation : annotations[index + offset].secondaryStructure); } + @Override public String toString() { char[] string = new char[max - offset]; @@ -710,12 +719,13 @@ public class AlignmentAnnotation if (annotation.sequenceMapping != null) { Integer p = null; - sequenceMapping = new Hashtable(); - Enumeration pos = annotation.sequenceMapping.keys(); - while (pos.hasMoreElements()) + sequenceMapping = new HashMap(); + Iterator pos = annotation.sequenceMapping.keySet() + .iterator(); + while (pos.hasNext()) { // could optimise this! - p = (Integer) pos.nextElement(); + p = pos.next(); Annotation a = annotation.sequenceMapping.get(p); if (a == null) { @@ -789,11 +799,11 @@ public class AlignmentAnnotation int epos = sequenceRef.findPosition(endRes); if (sequenceMapping != null) { - Hashtable newmapping = new Hashtable(); - Enumeration e = sequenceMapping.keys(); - while (e.hasMoreElements()) + Map newmapping = new HashMap(); + Iterator e = sequenceMapping.keySet().iterator(); + while (e.hasNext()) { - Integer pos = (Integer) e.nextElement(); + Integer pos = e.next(); if (pos.intValue() >= spos && pos.intValue() <= epos) { newmapping.put(pos, sequenceMapping.get(pos)); @@ -836,9 +846,10 @@ public class AlignmentAnnotation * * @return DOCUMENT ME! */ + @Override public String toString() { - StringBuffer buffer = new StringBuffer(); + StringBuilder buffer = new StringBuilder(256); for (int i = 0; i < annotations.length; i++) { @@ -911,7 +922,7 @@ public class AlignmentAnnotation { return; } - sequenceMapping = new java.util.Hashtable(); + sequenceMapping = new HashMap(); int seqPos; @@ -1223,7 +1234,7 @@ public class AlignmentAnnotation .getTo() == sq.getDatasetSequence()) : false; // TODO build a better annotation element map and get rid of annotations[] - Hashtable mapForsq = new Hashtable(); + Map mapForsq = new HashMap(); if (sequenceMapping != null) { if (sp2sq != null) @@ -1275,7 +1286,8 @@ public class AlignmentAnnotation { if (mapping != null) { - Hashtable old = sequenceMapping, remap = new Hashtable(); + Map old = sequenceMapping; + Map remap = new HashMap(); int index = -1; for (int mp[] : mapping) { diff --git a/src/jalview/datamodel/AlignmentI.java b/src/jalview/datamodel/AlignmentI.java index ea4dad4..67e5743 100755 --- a/src/jalview/datamodel/AlignmentI.java +++ b/src/jalview/datamodel/AlignmentI.java @@ -5,16 +5,16 @@ * 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 + * modify it under the terms of the GNU General 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. + * PURPOSE. See the GNU General License for more details. * - * You should have received a copy of the GNU General Public License + * You should have received a copy of the GNU General License * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ @@ -23,6 +23,7 @@ package jalview.datamodel; import java.util.Hashtable; import java.util.List; import java.util.Map; +import java.util.Set; /** * Data structure to hold and manipulate a multiple sequence alignment @@ -34,15 +35,16 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return Number of sequences in alignment */ - public int getHeight(); + int getHeight(); /** + * * Calculates the maximum width of the alignment, including gaps. * * @return Greatest sequence length within alignment. */ @Override - public int getWidth(); + int getWidth(); /** * Calculates if this set of sequences (visible and invisible) are all the @@ -50,7 +52,7 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return true if all sequences in alignment are the same length */ - public boolean isAligned(); + boolean isAligned(); /** * Calculates if this set of sequences is all the same length @@ -59,7 +61,7 @@ public interface AlignmentI extends AnnotatedCollectionI * optionally exclude hidden sequences from test * @return true if all (or just visible) sequences are the same length */ - public boolean isAligned(boolean includeHidden); + boolean isAligned(boolean includeHidden); /** * Gets sequences as a Synchronized collection @@ -67,14 +69,14 @@ public interface AlignmentI extends AnnotatedCollectionI * @return All sequences in alignment. */ @Override - public List getSequences(); + List getSequences(); /** * Gets sequences as a SequenceI[] * * @return All sequences in alignment. */ - public SequenceI[] getSequencesArray(); + SequenceI[] getSequencesArray(); /** * Find a specific sequence in this alignment. @@ -84,7 +86,14 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return SequenceI at given index. */ - public SequenceI getSequenceAt(int i); + SequenceI getSequenceAt(int i); + + /** + * Returns a map of lists of sequences keyed by sequence name. + * + * @return + */ + Map> getSequencesByName(); /** * Add a new sequence to this alignment. @@ -92,7 +101,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param seq * New sequence will be added at end of alignment. */ - public void addSequence(SequenceI seq); + void addSequence(SequenceI seq); /** * Used to set a particular index of the alignment with the given sequence. @@ -102,7 +111,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param seq * New sequence to be inserted. */ - public void setSequenceAt(int i, SequenceI seq); + void setSequenceAt(int i, SequenceI seq); /** * Deletes a sequence from the alignment @@ -110,7 +119,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param s * Sequence to be deleted. */ - public void deleteSequence(SequenceI s); + void deleteSequence(SequenceI s); /** * Deletes a sequence from the alignment. @@ -118,7 +127,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param i * Index of sequence to be deleted. */ - public void deleteSequence(int i); + void deleteSequence(int i); /** * Finds sequence in alignment using sequence name as query. @@ -128,9 +137,9 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return Sequence matching query, if found. If not found returns null. */ - public SequenceI findName(String name); + SequenceI findName(String name); - public SequenceI[] findSequenceMatch(String name); + SequenceI[] findSequenceMatch(String name); /** * Finds index of a given sequence in the alignment. @@ -140,7 +149,7 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return Index of sequence within the alignment or -1 if not found */ - public int findIndex(SequenceI s); + int findIndex(SequenceI s); /** * Finds group that given sequence is part of. @@ -151,7 +160,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @return First group found for sequence. WARNING : Sequences may be members * of several groups. This method is incomplete. */ - public SequenceGroup findGroup(SequenceI s); + SequenceGroup findGroup(SequenceI s); /** * Finds all groups that a given sequence is part of. @@ -161,7 +170,7 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return All groups containing given sequence. */ - public SequenceGroup[] findAllGroups(SequenceI s); + SequenceGroup[] findAllGroups(SequenceI s); /** * Adds a new SequenceGroup to this alignment. @@ -169,7 +178,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param sg * New group to be added. */ - public void addGroup(SequenceGroup sg); + void addGroup(SequenceGroup sg); /** * Deletes a specific SequenceGroup @@ -177,19 +186,19 @@ public interface AlignmentI extends AnnotatedCollectionI * @param g * Group will be deleted from alignment. */ - public void deleteGroup(SequenceGroup g); + void deleteGroup(SequenceGroup g); /** * Get all the groups associated with this alignment. * * @return All groups as a list. */ - public List getGroups(); + List getGroups(); /** * Deletes all groups from this alignment. */ - public void deleteAllGroups(); + void deleteAllGroups(); /** * Adds a new AlignmentAnnotation to this alignment @@ -197,7 +206,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @note Care should be taken to ensure that annotation is at least as wide as * the longest sequence in the alignment for rendering purposes. */ - public void addAnnotation(AlignmentAnnotation aa); + void addAnnotation(AlignmentAnnotation aa); /** * moves annotation to a specified index in alignment annotation display stack @@ -207,7 +216,16 @@ public interface AlignmentI extends AnnotatedCollectionI * @param index * the destination position */ - public void setAnnotationIndex(AlignmentAnnotation aa, int index); + void setAnnotationIndex(AlignmentAnnotation aa, int index); + + /** + * Delete all annotations, including auto-calculated if the flag is set true. + * Returns true if at least one annotation was deleted, else false. + * + * @param includingAutoCalculated + * @return + */ + boolean deleteAllAnnotations(boolean includingAutoCalculated); /** * Deletes a specific AlignmentAnnotation from the alignment, and removes its @@ -219,7 +237,7 @@ public interface AlignmentI extends AnnotatedCollectionI * the annotation to delete * @return true if annotation was deleted from this alignment. */ - public boolean deleteAnnotation(AlignmentAnnotation aa); + boolean deleteAnnotation(AlignmentAnnotation aa); /** * Deletes a specific AlignmentAnnotation from the alignment, and optionally @@ -235,7 +253,7 @@ public interface AlignmentI extends AnnotatedCollectionI * into the alignment * @return true if annotation was deleted from this alignment. */ - public boolean deleteAnnotation(AlignmentAnnotation aa, boolean unhook); + boolean deleteAnnotation(AlignmentAnnotation aa, boolean unhook); /** * Get the annotation associated with this alignment (this can be null if no @@ -244,7 +262,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @return array of AlignmentAnnotation objects */ @Override - public AlignmentAnnotation[] getAlignmentAnnotation(); + AlignmentAnnotation[] getAlignmentAnnotation(); /** * Change the gap character used in this alignment to 'gc' @@ -252,34 +270,34 @@ public interface AlignmentI extends AnnotatedCollectionI * @param gc * the new gap character. */ - public void setGapCharacter(char gc); + void setGapCharacter(char gc); /** * Get the gap character used in this alignment * * @return gap character */ - public char getGapCharacter(); + char getGapCharacter(); /** * Test for all nucleotide alignment * * @return true if alignment is nucleotide sequence */ - public boolean isNucleotide(); + boolean isNucleotide(); /** * Test if alignment contains RNA structure * * @return true if RNA structure AligmnentAnnotation was added to alignment */ - public boolean hasRNAStructure(); + boolean hasRNAStructure(); /** * Set alignment to be a nucleotide sequence * */ - public void setNucleotide(boolean b); + void setNucleotide(boolean b); /** * Get the associated dataset for the alignment. @@ -287,7 +305,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @return Alignment containing dataset sequences or null of this is a * dataset. */ - public Alignment getDataset(); + Alignment getDataset(); /** * Set the associated dataset for the alignment, or create one. @@ -295,23 +313,23 @@ public interface AlignmentI extends AnnotatedCollectionI * @param dataset * The dataset alignment or null to construct one. */ - public void setDataset(Alignment dataset); + void setDataset(Alignment dataset); /** * pads sequences with gaps (to ensure the set looks like an alignment) * * @return boolean true if alignment was modified */ - public boolean padGaps(); + boolean padGaps(); - public HiddenSequences getHiddenSequences(); + HiddenSequences getHiddenSequences(); /** * Compact representation of alignment * * @return CigarArray */ - public CigarArray getCompactAlignment(); + CigarArray getCompactAlignment(); /** * Set an arbitrary key value pair for an alignment. Note: both key and value @@ -320,7 +338,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param key * @param value */ - public void setProperty(Object key, Object value); + void setProperty(Object key, Object value); /** * Get a named property from the alignment. @@ -328,21 +346,21 @@ public interface AlignmentI extends AnnotatedCollectionI * @param key * @return value of property */ - public Object getProperty(Object key); + Object getProperty(Object key); /** * Get the property hashtable. * * @return hashtable of alignment properties (or null if none are defined) */ - public Hashtable getProperties(); + Hashtable getProperties(); /** * add a reference to a frame of aligned codons for this alignment * * @param codons */ - public void addCodonFrame(AlignedCodonFrame codons); + void addCodonFrame(AlignedCodonFrame codons); /** * remove a particular codon frame reference from this alignment @@ -350,27 +368,24 @@ public interface AlignmentI extends AnnotatedCollectionI * @param codons * @return true if codon frame was removed. */ - public boolean removeCodonFrame(AlignedCodonFrame codons); + boolean removeCodonFrame(AlignedCodonFrame codons); /** * get all codon frames associated with this alignment * * @return */ - public AlignedCodonFrame[] getCodonFrames(); + Set getCodonFrames(); /** - * get a particular codon frame - * - * @param index - * @return + * Set the codon frame mappings (replacing any existing set). */ - public AlignedCodonFrame getCodonFrame(int index); + void setCodonFrames(Set acfs); /** * get codon frames involving sequenceI */ - public AlignedCodonFrame[] getCodonFrame(SequenceI seq); + List getCodonFrame(SequenceI seq); /** * find sequence with given name in alignment @@ -382,7 +397,7 @@ public interface AlignmentI extends AnnotatedCollectionI * tried * @return matched sequence or null */ - public SequenceI findName(String token, boolean b); + SequenceI findName(String token, boolean b); /** * find next sequence with given name in alignment starting after a given @@ -398,7 +413,7 @@ public interface AlignmentI extends AnnotatedCollectionI * tried * @return matched sequence or null */ - public SequenceI findName(SequenceI startAfter, String token, boolean b); + SequenceI findName(SequenceI startAfter, String token, boolean b); /** * find first sequence in alignment which is involved in the given search @@ -407,7 +422,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param results * @return -1 or index of sequence in alignment */ - public int findIndex(SearchResults results); + int findIndex(SearchResults results); /** * append sequences and annotation from another alignment object to this one. @@ -420,7 +435,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param toappend * - the alignment to be appended. */ - public void append(AlignmentI toappend); + void append(AlignmentI toappend); /** * Justify the sequences to the left or right by deleting and inserting gaps @@ -430,7 +445,7 @@ public interface AlignmentI extends AnnotatedCollectionI * true if alignment padded to right, false to justify to left * @return true if alignment was changed TODO: return undo object */ - public boolean justify(boolean right); + boolean justify(boolean right); /** * add given annotation row at given position (0 is start, -1 is end) @@ -438,7 +453,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param consensus * @param i */ - public void addAnnotation(AlignmentAnnotation consensus, int i); + void addAnnotation(AlignmentAnnotation consensus, int i); /** * search for or create a specific annotation row on the alignment @@ -458,7 +473,7 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return existing annotation matching the given attributes */ - public AlignmentAnnotation findOrCreateAnnotation(String name, + AlignmentAnnotation findOrCreateAnnotation(String name, String calcId, boolean autoCalc, SequenceI seqRef, SequenceGroup groupRef); @@ -472,7 +487,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param up * @param i */ - public void moveSelectedSequencesByOne(SequenceGroup sg, + void moveSelectedSequencesByOne(SequenceGroup sg, Map map, boolean up); /** @@ -481,5 +496,25 @@ public interface AlignmentI extends AnnotatedCollectionI * * @param alignmentAnnotation */ - public void validateAnnotation(AlignmentAnnotation alignmentAnnotation); + void validateAnnotation(AlignmentAnnotation alignmentAnnotation); + + /** + * Align this alignment the same as the given one. If both of the same type + * (nucleotide/protein) then align both identically. If this is nucleotide and + * the other is protein, make 3 gaps for each gap in the protein sequences. If + * this is protein and the other is nucleotide, insert a gap for each 3 gaps + * (or part thereof) between nucleotide bases. Returns the number of mapped + * sequences that were realigned . + * + * @param al + * @return + */ + int alignAs(AlignmentI al); + + /** + * Returns the set of distinct sequence names in the alignment. + * + * @return + */ + Set getSequenceNames(); } diff --git a/src/jalview/datamodel/AlignmentOrder.java b/src/jalview/datamodel/AlignmentOrder.java index 0d2a948..ccc9bfa 100755 --- a/src/jalview/datamodel/AlignmentOrder.java +++ b/src/jalview/datamodel/AlignmentOrder.java @@ -20,7 +20,9 @@ */ package jalview.datamodel; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; public class AlignmentOrder { @@ -51,7 +53,7 @@ public class AlignmentOrder private String Name; - private Vector Order = null; + private List Order = null; /** * Creates a new AlignmentOrder object. @@ -64,9 +66,8 @@ public class AlignmentOrder * AlignmentOrder * * @param anOrder - * Vector */ - public AlignmentOrder(Vector anOrder) + public AlignmentOrder(List anOrder) { Order = anOrder; } @@ -79,11 +80,11 @@ public class AlignmentOrder */ public AlignmentOrder(AlignmentI orderFrom) { - Order = new Vector(); + Order = new ArrayList(); - for (int i = 0, ns = orderFrom.getHeight(); i < ns; i++) + for (SequenceI seq : orderFrom.getSequences()) { - Order.addElement(orderFrom.getSequenceAt(i)); + Order.add(seq); } } @@ -95,12 +96,7 @@ public class AlignmentOrder */ public AlignmentOrder(SequenceI[] orderFrom) { - Order = new Vector(); - - for (int i = 0, ns = orderFrom.length; i < ns; i++) - { - Order.addElement(orderFrom[i]); - } + Order = new ArrayList(Arrays.asList(orderFrom)); } /** @@ -151,7 +147,7 @@ public class AlignmentOrder * @param Order * DOCUMENT ME! */ - public void setOrder(Vector Order) + public void setOrder(List Order) { this.Order = Order; } @@ -161,7 +157,7 @@ public class AlignmentOrder * * @return DOCUMENT ME! */ - public Vector getOrder() + public List getOrder() { return Order; } @@ -178,7 +174,7 @@ public class AlignmentOrder int found = Order.indexOf(oldref); if (found > -1) { - Order.setElementAt(newref, found); + Order.set(found, newref); } return found > -1; } @@ -189,9 +185,14 @@ public class AlignmentOrder * @param o * @return true if o orders the same sequenceI objects in the same way */ - public boolean equals(AlignmentOrder o) + @Override + public boolean equals(Object o) { - return equals(o, true); + if (o == null || !(o instanceof AlignmentOrder)) + { + return false; + } + return equals((AlignmentOrder) o, true); } /** @@ -223,7 +224,7 @@ public class AlignmentOrder { for (int i = 0, j = o.Order.size(); i < j; i++) { - if (Order.elementAt(i) != o.Order.elementAt(i)) + if (Order.get(i) != o.Order.get(i)) { return false; } @@ -271,7 +272,7 @@ public class AlignmentOrder } if (Order != null && o.Order != null) { - Vector c, s; + List c, s; if (o.Order.size() > Order.size()) { c = o.Order; @@ -292,7 +293,7 @@ public class AlignmentOrder int last = -1; for (int i = 0, j = s.size(); i < j; i++) { - int pos = c.indexOf(s.elementAt(i)); // JBPNote - optimize by + int pos = c.indexOf(s.get(i)); // JBPNote - optimize by // incremental position search if (pos > last) { diff --git a/src/jalview/datamodel/AlignmentView.java b/src/jalview/datamodel/AlignmentView.java index f73fb74..b36a0a5 100644 --- a/src/jalview/datamodel/AlignmentView.java +++ b/src/jalview/datamodel/AlignmentView.java @@ -179,7 +179,9 @@ public class AlignmentView sgrps[g] = new ScGroup(); sgrps[g].sg = new SequenceGroup(sg); addedgps[g] = false; - seqsets.set(g, sg.getSequences(null)); + // can't set entry 0 in an empty list + // seqsets.set(g, sg.getSequences(null)); + seqsets.add(sg.getSequences()); } // seqsets now contains vectors (should be sets) for each group, so we can // track when we've done with the group diff --git a/src/jalview/datamodel/ColumnSelection.java b/src/jalview/datamodel/ColumnSelection.java index b7bc40e..835d7e9 100644 --- a/src/jalview/datamodel/ColumnSelection.java +++ b/src/jalview/datamodel/ColumnSelection.java @@ -25,8 +25,7 @@ import jalview.viewmodel.annotationfilter.AnnotationFilterParameter; import jalview.viewmodel.annotationfilter.AnnotationFilterParameter.SearchableAnnotationField; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Enumeration; +import java.util.Collections; import java.util.List; import java.util.Vector; @@ -35,7 +34,7 @@ import java.util.Vector; */ public class ColumnSelection { - Vector selected = new Vector(); + Vector selected = new Vector(); // Vector of int [] {startCol, endCol} Vector hiddenColumns; @@ -64,7 +63,7 @@ public class ColumnSelection } /** - * removes col from selection + * Removes value 'col' from the selection (not the col'th item) * * @param col * index of column to be removed @@ -75,6 +74,8 @@ public class ColumnSelection if (selected.contains(colInt)) { + // if this ever changes to List.remove(), ensure Integer not int argument + // as List.remove(int i) removes the i'th item which is wrong selected.removeElement(colInt); } } @@ -131,7 +132,7 @@ public class ColumnSelection */ public int columnAt(int i) { - return ((Integer) selected.elementAt(i)).intValue(); + return selected.elementAt(i).intValue(); } /** @@ -201,6 +202,7 @@ public class ColumnSelection if (temp >= start) { + // if this ever changes to List.set(), swap parameter order!! selected.setElementAt(new Integer(temp - change), i); } } @@ -258,6 +260,7 @@ public class ColumnSelection if (temp >= start) { + // if this ever changes to List.set(), swap parameter order!! selected.setElementAt(new Integer(temp - change), i); } } @@ -303,13 +306,13 @@ public class ColumnSelection { if (shiftrecord != null) { - Vector shifts = shiftrecord.shifts; + final List shifts = shiftrecord.getShifts(); if (shifts != null && shifts.size() > 0) { int shifted = 0; for (int i = 0, j = shifts.size(); i < j; i++) { - int[] sh = (int[]) shifts.elementAt(i); + int[] sh = shifts.get(i); // compensateForEdit(shifted+sh[0], sh[1]); compensateForDelEdits(shifted + sh[0], sh[1]); shifted -= sh[1]; @@ -324,16 +327,17 @@ public class ColumnSelection * removes intersection of position,length ranges in deletions from the * start,end regions marked in intervals. * - * @param deletions + * @param shifts * @param intervals * @return */ - private boolean pruneIntervalVector(Vector deletions, Vector intervals) + private boolean pruneIntervalVector(final List shifts, + Vector intervals) { boolean pruned = false; - int i = 0, j = intervals.size() - 1, s = 0, t = deletions.size() - 1; - int hr[] = (int[]) intervals.elementAt(i); - int sr[] = (int[]) deletions.elementAt(s); + int i = 0, j = intervals.size() - 1, s = 0, t = shifts.size() - 1; + int hr[] = intervals.elementAt(i); + int sr[] = shifts.get(s); while (i <= j && s <= t) { boolean trailinghn = hr[1] >= sr[0]; @@ -341,7 +345,7 @@ public class ColumnSelection { if (i < j) { - hr = (int[]) intervals.elementAt(++i); + hr = intervals.elementAt(++i); } else { @@ -354,7 +358,7 @@ public class ColumnSelection { // leadinghc disjoint or not a deletion if (s < t) { - sr = (int[]) deletions.elementAt(++s); + sr = shifts.get(++s); } else { @@ -374,7 +378,7 @@ public class ColumnSelection j--; if (i <= j) { - hr = (int[]) intervals.elementAt(i); + hr = intervals.elementAt(i); } continue; } @@ -400,7 +404,7 @@ public class ColumnSelection // sr contained in hr if (s < t) { - sr = (int[]) deletions.elementAt(++s); + sr = shifts.get(++s); } else { @@ -414,15 +418,16 @@ public class ColumnSelection // operations. } - private boolean pruneColumnList(Vector deletion, Vector list) + private boolean pruneColumnList(final List shifts, + Vector list) { - int s = 0, t = deletion.size(); - int[] sr = (int[]) list.elementAt(s++); + int s = 0, t = shifts.size(); + int[] sr = shifts.get(s++); boolean pruned = false; int i = 0, j = list.size(); while (i < j && s <= t) { - int c = ((Integer) list.elementAt(i++)).intValue(); + int c = list.elementAt(i++).intValue(); if (sr[0] <= c) { if (sr[1] + sr[0] >= c) @@ -434,7 +439,7 @@ public class ColumnSelection { if (s < t) { - sr = (int[]) deletion.elementAt(s); + sr = shifts.get(s); } s++; } @@ -453,7 +458,7 @@ public class ColumnSelection { if (deletions != null) { - Vector shifts = deletions.shifts; + final List shifts = deletions.getShifts(); if (shifts != null && shifts.size() > 0) { // delete any intervals intersecting. @@ -485,8 +490,8 @@ public class ColumnSelection */ public List getHiddenColumns() { - return hiddenColumns == null ? Arrays.asList(new int[] - {}) : hiddenColumns; + return hiddenColumns == null ? Collections. emptyList() + : hiddenColumns; } /** @@ -644,7 +649,7 @@ public class ColumnSelection { if (hiddenColumns == null) { - hiddenColumns = new Vector(); + hiddenColumns = new Vector(); } boolean added = false; @@ -780,7 +785,7 @@ public class ColumnSelection { if (copy.selected != null) { - selected = new Vector(); + selected = new Vector(); for (int i = 0, j = copy.selected.size(); i < j; i++) { selected.addElement(copy.selected.elementAt(i)); @@ -788,7 +793,7 @@ public class ColumnSelection } if (copy.hiddenColumns != null) { - hiddenColumns = new Vector(copy.hiddenColumns.size()); + hiddenColumns = new Vector(copy.hiddenColumns.size()); for (int i = 0, j = copy.hiddenColumns.size(); i < j; i++) { int[] rh, cp; @@ -885,7 +890,7 @@ public class ColumnSelection { if (hiddenColumns != null && hiddenColumns.size() > 0) { - Vector visiblecontigs = new Vector(); + List visiblecontigs = new ArrayList(); List regions = getHiddenColumns(); int vstart = start; @@ -904,7 +909,7 @@ public class ColumnSelection } if (hideStart > vstart) { - visiblecontigs.addElement(new int[] + visiblecontigs.add(new int[] { vstart, hideStart - 1 }); } vstart = hideEnd + 1; @@ -912,18 +917,18 @@ public class ColumnSelection if (vstart < end) { - visiblecontigs.addElement(new int[] + visiblecontigs.add(new int[] { vstart, end - 1 }); } int[] vcontigs = new int[visiblecontigs.size() * 2]; for (int i = 0, j = visiblecontigs.size(); i < j; i++) { - int[] vc = (int[]) visiblecontigs.elementAt(i); - visiblecontigs.setElementAt(null, i); + int[] vc = visiblecontigs.get(i); + visiblecontigs.set(i, null); vcontigs[i * 2] = vc[0]; vcontigs[i * 2 + 1] = vc[1]; } - visiblecontigs.removeAllElements(); + visiblecontigs.clear(); return vcontigs; } else @@ -970,7 +975,7 @@ public class ColumnSelection if (hiddenColumns != null && hiddenColumns.size() > 0) { // then mangle the alignmentAnnotation annotation array - Vector annels = new Vector(); + Vector annels = new Vector(); Annotation[] els = null; List regions = getHiddenColumns(); int blockStart = start, blockEnd = end; @@ -1026,12 +1031,12 @@ public class ColumnSelection { return; } - Enumeration e = annels.elements(); + alignmentAnnotation.annotations = new Annotation[w]; w = 0; - while (e.hasMoreElements()) + + for (Annotation [] chnk : annels) { - Annotation[] chnk = (Annotation[]) e.nextElement(); System.arraycopy(chnk, 0, alignmentAnnotation.annotations, w, chnk.length); w += chnk.length; @@ -1079,15 +1084,13 @@ public class ColumnSelection { if (colsel != null && colsel.size() > 0) { - Enumeration e = colsel.getSelected().elements(); - while (e.hasMoreElements()) + for (Integer col : colsel.getSelected()) { - Object eo = e.nextElement(); - if (hiddenColumns != null && isVisible(((Integer) eo).intValue())) + if (hiddenColumns != null && isVisible(col.intValue())) { - if (!selected.contains(eo)) + if (!selected.contains(col)) { - selected.addElement(eo); + selected.addElement(col); } } } @@ -1102,22 +1105,20 @@ public class ColumnSelection */ public void setElementsFrom(ColumnSelection colsel) { - selected = new Vector(); + selected = new Vector(); if (colsel.selected != null && colsel.selected.size() > 0) { if (hiddenColumns != null && hiddenColumns.size() > 0) { // only select visible columns in this columns selection - selected = new Vector(); addElementsFrom(colsel); } else { // add everything regardless - Enumeration en = colsel.selected.elements(); - while (en.hasMoreElements()) + for (Integer col : colsel.getSelected()) { - selected.addElement(en.nextElement()); + addElement(col); } } } diff --git a/src/jalview/datamodel/DBRefEntry.java b/src/jalview/datamodel/DBRefEntry.java index bc1d610..0581845 100755 --- a/src/jalview/datamodel/DBRefEntry.java +++ b/src/jalview/datamodel/DBRefEntry.java @@ -69,12 +69,20 @@ public class DBRefEntry (entry.map == null ? null : new Mapping(entry.map))); } - public boolean equals(DBRefEntry entry) + @Override + public boolean equals(Object o) { + // TODO should also override hashCode to ensure equal objects have equal + // hashcodes + if (o == null || !(o instanceof DBRefEntry)) + { + return false; + } + DBRefEntry entry = (DBRefEntry) o; if (entry == this) + { return true; - if (entry == null) - return false; + } if (equalRef(entry) && ((map == null && entry.map == null) || (map != null && entry.map != null && map.equals(entry.map)))) @@ -97,7 +105,9 @@ public class DBRefEntry return false; } if (entry == this) + { return true; + } if ((source != null && entry.source != null && source .equalsIgnoreCase(entry.source)) && (accessionId != null && entry.accessionId != null && accessionId @@ -183,4 +193,9 @@ public class DBRefEntry return ((source != null) ? source : "") + ":" + ((accessionId != null) ? accessionId : ""); } + + public String toString() + { + return getSrcAccString(); + } } diff --git a/src/jalview/datamodel/DBRefSource.java b/src/jalview/datamodel/DBRefSource.java index b1824f7..6982594 100755 --- a/src/jalview/datamodel/DBRefSource.java +++ b/src/jalview/datamodel/DBRefSource.java @@ -38,12 +38,15 @@ public class DBRefSource /** * UNIPROT Entry Name */ - public static String UP_NAME = "UNIPROT_NAME"; + public static String UP_NAME = "UNIPROT_NAME".toUpperCase(); /** * Uniprot Knowledgebase/TrEMBL as served from EMBL protein products. */ - public static final String UNIPROTKB = "UniProtKB/TrEMBL"; + public static final String UNIPROTKB = "UniProtKB/TrEMBL".toUpperCase(); + + public static final String EMBLCDSProduct = "EMBLCDSProtein" + .toUpperCase(); /** * PDB Entry Code @@ -73,7 +76,7 @@ public class DBRefSource /** * GeneDB ID */ - public static final String GENEDB = "GeneDB"; + public static final String GENEDB = "GeneDB".toUpperCase(); /** * List of databases whose sequences might have coding regions annotated @@ -85,10 +88,10 @@ public class DBRefSource { EMBLCDS, GENEDB }; public static final String[] PROTEINDBS = - { UNIPROT, PDB, UNIPROTKB }; + { UNIPROT, PDB, UNIPROTKB, EMBLCDSProduct }; public static final String[] PROTEINSEQ = - { UNIPROT, UNIPROTKB }; + { UNIPROT, UNIPROTKB, EMBLCDSProduct }; public static final String[] PROTEINSTR = { PDB }; diff --git a/src/jalview/datamodel/IncompleteCodonException.java b/src/jalview/datamodel/IncompleteCodonException.java new file mode 100644 index 0000000..f716a53 --- /dev/null +++ b/src/jalview/datamodel/IncompleteCodonException.java @@ -0,0 +1,13 @@ +package jalview.datamodel; + +/** + * An exception to indicate that less than 3 nucleotide bases are available when + * trying to form a codon. + * + * @author gmcarstairs + * + */ +public class IncompleteCodonException extends RuntimeException +{ + +} diff --git a/src/jalview/datamodel/Mapping.java b/src/jalview/datamodel/Mapping.java index e307143..559ae4c 100644 --- a/src/jalview/datamodel/Mapping.java +++ b/src/jalview/datamodel/Mapping.java @@ -20,21 +20,255 @@ */ package jalview.datamodel; -import java.util.Vector; - import jalview.util.MapList; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Vector; + public class Mapping { /** + * An iterator that serves the aligned codon positions (with their protein + * products). + * + * @author gmcarstairs + * + */ + public class AlignedCodonIterator implements Iterator + { + /* + * The gap character used in the aligned sequence + */ + private final char gap; + + /* + * The characters of the aligned sequence e.g. "-cGT-ACgTG-" + */ + private final char[] alignedSeq; + + /* + * Next position (base 0) in the aligned sequence + */ + private int alignedColumn = 0; + + /* + * Count of bases up to and including alignedColumn position + */ + private int alignedBases = 0; + + /* + * [start, end] from ranges (base 1) + */ + private Iterator fromRanges; + + /* + * [start, end] to ranges (base 1) + */ + private Iterator toRanges; + + /* + * The current [start, end] (base 1) from range + */ + private int[] currentFromRange = null; + + /* + * The current [start, end] (base 1) to range + */ + private int[] currentToRange = null; + + /* + * The next 'from' position (base 1) to process + */ + private int fromPosition = 0; + + /* + * The next 'to' position (base 1) to process + */ + private int toPosition = 0; + + /** + * Constructor + * + * @param cs + * the aligned sequence characters + * @param gapChar + */ + public AlignedCodonIterator(char[] cs, char gapChar) + { + this.alignedSeq = cs; + this.gap = gapChar; + fromRanges = map.getFromRanges().iterator(); + toRanges = map.getToRanges().iterator(); + if (fromRanges.hasNext()) + { + currentFromRange = fromRanges.next(); + fromPosition = currentFromRange[0]; + } + if (toRanges.hasNext()) + { + currentToRange = toRanges.next(); + toPosition = currentToRange[0]; + } + } + + /** + * Returns true unless we have already traversed the whole mapping. + */ + @Override + public boolean hasNext() + { + if (fromRanges.hasNext()) + { + return true; + } + if (currentFromRange == null || fromPosition >= currentFromRange[1]) + { + return false; + } + return true; + } + + /** + * Returns the next codon's aligned positions, and translated value. + * + * @throws NoSuchElementException + * if hasNext() would have returned false + * @throws IncompleteCodonException + * if not enough mapped bases are left to make up a codon + */ + @Override + public AlignedCodon next() throws IncompleteCodonException + { + if (!hasNext()) + { + throw new NoSuchElementException(); + } + + int[] codon = getNextCodon(); + int[] alignedCodon = getAlignedCodon(codon); + + String peptide = getPeptide(); + return new AlignedCodon(alignedCodon[0], alignedCodon[1], + alignedCodon[2], peptide); + } + + /** + * Retrieve the translation as the 'mapped to' position in the mapped to + * sequence. + * + * @return + */ + private String getPeptide() + { + // TODO should ideally handle toRatio other than 1 as well... + // i.e. code like getNextCodon() + if (toPosition <= currentToRange[1]) { + char pep = Mapping.this.to.getSequence()[toPosition - 1]; + toPosition++; + return String.valueOf(pep); + } + if (!toRanges.hasNext()) + { + throw new NoSuchElementException("Ran out of peptide at position " + + toPosition); + } + currentToRange = toRanges.next(); + toPosition = currentToRange[0]; + return getPeptide(); + } + + /** + * Get the (base 1) dataset positions for the next codon in the mapping. + * + * @throws IncompleteCodonException + * if less than 3 remaining bases are mapped + */ + private int[] getNextCodon() + { + int[] codon = new int[3]; + int codonbase = 0; + + while (codonbase < 3) + { + if (fromPosition <= currentFromRange[1]) + { + /* + * Add next position from the current start-end range + */ + codon[codonbase++] = fromPosition++; + } + else + { + /* + * Move to the next range - if there is one + */ + if (!fromRanges.hasNext()) + { + throw new IncompleteCodonException(); + } + currentFromRange = fromRanges.next(); + fromPosition = currentFromRange[0]; + } + } + return codon; + } + + /** + * Get the aligned column positions (base 0) for the given sequence + * positions (base 1), by counting ungapped characters in the aligned + * sequence. + * + * @param codon + * @return + */ + private int[] getAlignedCodon(int[] codon) + { + int[] aligned = new int[codon.length]; + for (int i = 0; i < codon.length; i++) + { + aligned[i] = getAlignedColumn(codon[i]); + } + return aligned; + } + + /** + * Get the aligned column position (base 0) for the given sequence position + * (base 1). + * + * @param sequencePos + * @return + */ + private int getAlignedColumn(int sequencePos) + { + while (alignedBases < sequencePos + && alignedColumn < alignedSeq.length) + { + if (alignedSeq[alignedColumn++] != gap) + { + alignedBases++; + } + } + return alignedColumn - 1; + } + + @Override + public void remove() + { + // ignore + } + + } + + /** * Contains the start-end pairs mapping from the associated sequence to the - * sequence in the database coordinate system it also takes care of step - * difference between coordinate systems + * sequence in the database coordinate system. It also takes care of step + * difference between coordinate systems. */ MapList map = null; /** - * The seuqence that map maps the associated seuqence to (if any). + * The sequence that map maps the associated sequence to (if any). */ SequenceI to = null; @@ -111,19 +345,33 @@ public class Mapping * @param other * @return */ - public boolean equals(Mapping other) + @Override + public boolean equals(Object o) { - if (other == null) + // TODO should override Object.hashCode() to ensure that equal objects have + // equal hashcodes + if (o == null || !(o instanceof Mapping)) + { return false; + } + Mapping other = (Mapping) o; if (other == this) + { return true; + } if (other.to != to) + { return false; + } if ((map != null && other.map == null) || (map == null && other.map != null)) + { return false; - if (map.equals(other.map)) + } + if ((map == null && other.map == null) || map.equals(other.map)) + { return true; + } return false; } @@ -251,7 +499,9 @@ public class Mapping vf[v].setBegin(frange[i]); vf[v].setEnd(frange[i + 1]); if (frange.length > 2) + { vf[v].setDescription(f.getDescription() + "\nPart " + (v + 1)); + } } return vf; } @@ -300,14 +550,18 @@ public class Mapping from = (map.getToLowest() < from) ? from : map.getToLowest(); to = (map.getToHighest() > to) ? to : map.getToHighest(); if (from > to) + { return null; + } } else { from = (map.getToHighest() > from) ? from : map.getToHighest(); to = (map.getToLowest() < to) ? to : map.getToLowest(); if (from < to) + { return null; + } } return map.locateInFrom(from, to); } @@ -333,14 +587,18 @@ public class Mapping from = (map.getFromLowest() < from) ? from : map.getFromLowest(); to = (map.getFromHighest() > to) ? to : map.getFromHighest(); if (from > to) + { return null; + } } else { from = (map.getFromHighest() > from) ? from : map.getFromHighest(); to = (map.getFromLowest() < to) ? to : map.getFromLowest(); if (from < to) + { return null; + } } return map.locateInTo(from, to); } @@ -455,4 +713,9 @@ public class Mapping super.finalize(); } + public Iterator getCodonIterator(SequenceI seq, char gapChar) + { + return new AlignedCodonIterator(seq.getSequence(), gapChar); + } + } diff --git a/src/jalview/datamodel/SearchResults.java b/src/jalview/datamodel/SearchResults.java index 07ceeb8..e62e58a 100755 --- a/src/jalview/datamodel/SearchResults.java +++ b/src/jalview/datamodel/SearchResults.java @@ -20,10 +20,81 @@ */ package jalview.datamodel; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Holds a list of search result matches, where each match is a contiguous + * stretch of a single sequence. + * + * @author gmcarstairs + * + */ public class SearchResults { - Match[] matches; + private List matches = new ArrayList(); + + public class Match + { + SequenceI sequence; + + /** + * Start position of match in sequence (base 1) + */ + int start; + + /** + * End position (inclusive) (base 1) + */ + int end; + + /** + * Constructor + * + * @param seq + * a sequence + * @param start + * start position of matched range (base 1) + * @param end + * end of matched range (inclusive, base 1) + */ + public Match(SequenceI seq, int start, int end) + { + sequence = seq; + this.start = start; + this.end = end; + } + + public SequenceI getSequence() + { + return sequence; + } + + public int getStart() + { + return start; + } + + public int getEnd() + { + return end; + } + + /** + * Returns the string of characters in the matched region. + */ + @Override + public String toString() + { + char[] chars = sequence.getSequence(); + // convert start/end to base 0 (with bounds check) + final int from = Math.max(start - 1, 0); + final int to = Math.min(end, chars.length + 1); + return String.valueOf(Arrays.copyOfRange(chars, from, to)); + } + } /** * This method replaces the old search results which merely held an alignment @@ -39,25 +110,7 @@ public class SearchResults */ public void addResult(SequenceI seq, int start, int end) { - if (matches == null) - { - matches = new Match[] - { new Match(seq, start, end) }; - return; - } - - int mSize = matches.length; - - Match[] tmp = new Match[mSize + 1]; - int m; - for (m = 0; m < mSize; m++) - { - tmp[m] = matches[m]; - } - - tmp[m] = new Match(seq, start, end); - - matches = tmp; + matches.add(new Match(seq, start, end)); } /** @@ -69,15 +122,11 @@ public class SearchResults */ public boolean involvesSequence(SequenceI sequence) { - if (matches == null || matches.length == 0) - { - return false; - } SequenceI ds = sequence.getDatasetSequence(); - for (int m = 0; m < matches.length; m++) + for (Match m : matches) { - if (matches[m].sequence != null - && (matches[m].sequence == sequence || matches[m].sequence == ds)) + if (m.sequence != null + && (m.sequence == sequence || m.sequence == ds)) { return true; } @@ -92,7 +141,7 @@ public class SearchResults */ public int[] getResults(SequenceI sequence, int start, int end) { - if (matches == null) + if (matches.isEmpty()) { return null; } @@ -101,22 +150,22 @@ public class SearchResults int[] tmp = null; int resultLength, matchStart = 0, matchEnd = 0; boolean mfound; - for (int m = 0; m < matches.length; m++) + for (Match m : matches) { mfound = false; - if (matches[m].sequence == sequence) + if (m.sequence == sequence) { mfound = true; // locate aligned position - matchStart = sequence.findIndex(matches[m].start) - 1; - matchEnd = sequence.findIndex(matches[m].end) - 1; + matchStart = sequence.findIndex(m.start) - 1; + matchEnd = sequence.findIndex(m.end) - 1; } - else if (matches[m].sequence == sequence.getDatasetSequence()) + else if (m.sequence == sequence.getDatasetSequence()) { mfound = true; // locate region in local context - matchStart = sequence.findIndex(matches[m].start) - 1; - matchEnd = sequence.findIndex(matches[m].end) - 1; + matchStart = sequence.findIndex(m.start) - 1; + matchEnd = sequence.findIndex(m.end) - 1; } if (mfound) { @@ -160,37 +209,71 @@ public class SearchResults public int getSize() { - return matches == null ? 0 : matches.length; + return matches.size(); } public SequenceI getResultSequence(int index) { - return matches[index].sequence; + return matches.get(index).sequence; } - public int getResultStart(int index) + /** + * Returns the start position of the i'th match in the search results. + * + * @param i + * @return + */ + public int getResultStart(int i) { - return matches[index].start; + return matches.get(i).start; } - public int getResultEnd(int index) + /** + * Returns the end position of the i'th match in the search results. + * + * @param i + * @return + */ + public int getResultEnd(int i) { - return matches[index].end; + return matches.get(i).end; } - class Match + /** + * Returns true if no search result matches are held. + * + * @return + */ + public boolean isEmpty() { - SequenceI sequence; - - int start; + return matches.isEmpty(); + } - int end; + /** + * Returns the list of matches. + * + * @return + */ + public List getResults() + { + return matches; + } - public Match(SequenceI seq, int start, int end) + /** + * Return the results as a string of characters. Meant for use when the + * context ensures that all matches are to regions of the same sequence + * (otherwise the result is meaningless). + * + * @return + */ + @Override + public String toString() + { + StringBuilder result = new StringBuilder(256); + for (Match m : matches) { - sequence = seq; - this.start = start; - this.end = end; + result.append(m.toString()); } + return result.toString(); } } diff --git a/src/jalview/datamodel/Sequence.java b/src/jalview/datamodel/Sequence.java index 0267f45..5c1fba5 100755 --- a/src/jalview/datamodel/Sequence.java +++ b/src/jalview/datamodel/Sequence.java @@ -21,6 +21,7 @@ package jalview.datamodel; import jalview.analysis.AlignSeq; +import jalview.util.StringUtils; import java.util.ArrayList; import java.util.Enumeration; @@ -326,13 +327,26 @@ public class Sequence implements SequenceI } /** - * DOCUMENT ME! + * Returns the sequence features (if any), looking first on the sequence, then + * on its dataset sequence, and so on until a non-null value is found (or + * none). This supports retrieval of sequence features stored on the sequence + * (as in the applet) or on the dataset sequence (as in the Desktop version). * - * @return DOCUMENT ME! + * @return */ public SequenceFeature[] getSequenceFeatures() { - return sequenceFeatures; + SequenceFeature[] features = sequenceFeatures; + + SequenceI seq = this; + int count = 0; // failsafe against loop in sequence.datasetsequence... + while (features == null && seq.getDatasetSequence() != null + && count++ < 10) + { + seq = seq.getDatasetSequence(); + features = ((Sequence) seq).sequenceFeatures; + } + return features; } public void addPDBId(PDBEntry entry) @@ -726,24 +740,12 @@ public class Sequence implements SequenceI return; } - char[] tmp; - - if (j >= sequence.length) - { - tmp = new char[i]; - System.arraycopy(sequence, 0, tmp, 0, i); - j = sequence.length; - } - else - { - tmp = new char[sequence.length - j + i]; - System.arraycopy(sequence, 0, tmp, 0, i); - System.arraycopy(sequence, j, tmp, i, sequence.length - j); - } + char[] tmp = StringUtils.deleteChars(sequence, i, j); boolean createNewDs = false; - // TODO: take a look at the new dataset creation validation method below - - // this could become time comsuming for large sequences - consider making it - // more efficient + // TODO: take a (second look) at the dataset creation validation method for + // the very large sequence case + int eindex = -1, sindex = -1; + boolean ecalc = false, scalc = false; for (int s = i; s < j; s++) { if (jalview.schemes.ResidueProperties.aaIndex[sequence[s]] != 23) @@ -754,7 +756,11 @@ public class Sequence implements SequenceI } else { - int sindex = findIndex(start) - 1; + if (!scalc) + { + sindex = findIndex(start) - 1; + scalc = true; + } if (sindex == s) { // delete characters including start of sequence @@ -764,7 +770,11 @@ public class Sequence implements SequenceI else { // delete characters after start. - int eindex = findIndex(end) - 1; + if (!ecalc) + { + eindex = findIndex(end) - 1; + ecalc = true; + } if (eindex < j) { // delete characters at end of sequence @@ -1024,7 +1034,7 @@ public class Sequence implements SequenceI AlignmentAnnotation _aa = new AlignmentAnnotation(aa); _aa.sequenceRef = datasetSequence; _aa.adjustForAlignment(); // uses annotation's own record of - // sequence-column mapping + // sequence-column mapping datasetSequence.addAlignmentAnnotation(_aa); } } @@ -1245,8 +1255,10 @@ public class Sequence implements SequenceI String label) { List result = new ArrayList(); - if (this.annotation != null) { - for (AlignmentAnnotation ann : annotation) { + if (this.annotation != null) + { + for (AlignmentAnnotation ann : annotation) + { if (ann.calcId != null && ann.calcId.equals(calcId) && ann.label != null && ann.label.equals(label)) { diff --git a/src/jalview/datamodel/SequenceFeature.java b/src/jalview/datamodel/SequenceFeature.java index 48b7f88..28ab82c 100755 --- a/src/jalview/datamodel/SequenceFeature.java +++ b/src/jalview/datamodel/SequenceFeature.java @@ -20,7 +20,8 @@ */ package jalview.datamodel; -import java.util.*; +import java.util.Hashtable; +import java.util.Vector; /** * DOCUMENT ME! @@ -42,7 +43,7 @@ public class SequenceFeature public Hashtable otherDetails; - public java.util.Vector links; + public Vector links; // Feature group can be set from a features file // as a group of features between STARTGROUP and ENDGROUP markers @@ -90,7 +91,7 @@ public class SequenceFeature } if (cpy.links != null && cpy.links.size() > 0) { - links = new Vector(); + links = new Vector(); for (int i = 0, iSize = cpy.links.size(); i < iSize; i++) { links.addElement(cpy.links.elementAt(i)); @@ -211,7 +212,7 @@ public class SequenceFeature { if (links == null) { - links = new java.util.Vector(); + links = new Vector(); } links.insertElementAt(labelLink, 0); @@ -283,7 +284,9 @@ public class SequenceFeature { String stat = (String) otherDetails.get("status"); if (stat != null) + { return new String(stat); + } } return null; } diff --git a/src/jalview/datamodel/SequenceGroup.java b/src/jalview/datamodel/SequenceGroup.java index 4727e5e..feb714a 100755 --- a/src/jalview/datamodel/SequenceGroup.java +++ b/src/jalview/datamodel/SequenceGroup.java @@ -1295,6 +1295,9 @@ public class SequenceGroup implements AnnotatedCollectionI return false; } + /** + * Remove all sequences from the group (leaving other properties unchanged). + */ public void clear() { synchronized (sequences) diff --git a/src/jalview/datamodel/SequenceI.java b/src/jalview/datamodel/SequenceI.java index 3808966..a9a7589 100755 --- a/src/jalview/datamodel/SequenceI.java +++ b/src/jalview/datamodel/SequenceI.java @@ -172,8 +172,7 @@ public interface SequenceI public String getDescription(); /** - * Return the alignment column for a sequence position * Return the alignment - * position for a sequence position + * Return the alignment column for a sequence position * * @param pos * lying from start to end @@ -220,9 +219,9 @@ public interface SequenceI * if necessary and adjusting start and end positions accordingly. * * @param i - * first column in range to delete + * first column in range to delete (inclusive) * @param j - * last column in range to delete + * last column in range to delete (exclusive) */ public void deleteChars(int i, int j); @@ -238,13 +237,12 @@ public interface SequenceI /** * DOCUMENT ME! - * - * @param i + * @param position * DOCUMENT ME! - * @param c + * @param ch * DOCUMENT ME! */ - public void insertCharAt(int i, int length, char c); + public void insertCharAt(int position, int count, char ch); /** * DOCUMENT ME! diff --git a/src/jalview/datamodel/xdb/embl/EmblEntry.java b/src/jalview/datamodel/xdb/embl/EmblEntry.java index 1a24415..fc57b27 100644 --- a/src/jalview/datamodel/xdb/embl/EmblEntry.java +++ b/src/jalview/datamodel/xdb/embl/EmblEntry.java @@ -425,9 +425,13 @@ public class EmblEntry { 1, dna.getLength() }, 1, 1)); // TODO: transform EMBL Database refs to canonical form if (dbRefs != null) + { for (Iterator i = dbRefs.iterator(); i.hasNext(); dna .addDBRef((DBRefEntry) i.next())) + { ; + } + } } try { @@ -440,7 +444,9 @@ public class EmblEntry { for (Iterator dbr = feature.dbRefs.iterator(); dbr.hasNext(); dna .addDBRef((DBRefEntry) dbr.next())) + { ; + } } } if (FeatureProperties.isCodingFeature(sourceDb, feature.getName())) @@ -456,7 +462,9 @@ public class EmblEntry { for (Iterator dbr = feature.dbRefs.iterator(); dbr.hasNext(); dna .addDBRef((DBRefEntry) dbr.next())) + { ; + } } } } @@ -582,8 +590,10 @@ public class EmblEntry } } Sequence product = null; + DBRefEntry protEMBLCDS = null; exon = adjustForPrStart(prstart, exon); - + boolean noProteinDbref=true; + if (prseq != null && prname != null && prid != null) { // extract proteins. @@ -659,8 +669,14 @@ public class EmblEntry // { 1prstart, prstart + prseq.length() - 1 }, 3, 1); pcdnaref.setMap(new Mapping(mp)); if (product != null) + { product.addDBRef(pcdnaref); - + protEMBLCDS = new DBRefEntry(pcdnaref); + protEMBLCDS.setSource(DBRefSource.EMBLCDSProduct); + product.addDBRef(protEMBLCDS); + + } + } } // add cds feature to dna seq - this may include the stop codon @@ -671,18 +687,20 @@ public class EmblEntry sf.setEnd(exon[xint + 1]); sf.setType(feature.getName()); sf.setFeatureGroup(sourceDb); - sf.setDescription("Exon " + (1 + (int) (xint / 2)) + sf.setDescription("Exon " + (1 + xint / 2) + " for protein '" + prname + "' EMBLCDS:" + prid); sf.setValue(FeatureProperties.EXONPOS, new Integer(1 + xint)); sf.setValue(FeatureProperties.EXONPRODUCT, prname); if (vals != null && vals.size() > 0) { - Enumeration kv = vals.elements(); + Enumeration kv = vals.keys(); while (kv.hasMoreElements()) { Object key = kv.nextElement(); if (key != null) + { sf.setValue(key.toString(), vals.get(key)); + } } } dna.addSequenceFeature(sf); @@ -712,6 +730,7 @@ public class EmblEntry + ref.getAccessionId()); } } + noProteinDbref = false; } if (product != null) { @@ -734,6 +753,33 @@ public class EmblEntry } dna.addDBRef(ref); } + if (noProteinDbref && product != null) + { + // add protein coding reference to dna sequence so xref matches + if (protEMBLCDS == null) + { + protEMBLCDS = new DBRefEntry(); + protEMBLCDS.setAccessionId(prid); + protEMBLCDS.setSource(DBRefSource.EMBLCDSProduct); + protEMBLCDS.setVersion(getVersion()); + protEMBLCDS + .setMap(new Mapping(product, map.getMap().getInverse())); + } + product.addDBRef(protEMBLCDS); + + // Add converse mapping reference + if (map != null) + { + Mapping pmap = new Mapping(product, protEMBLCDS.getMap().getMap() + .getInverse()); + DBRefEntry ncMap = new DBRefEntry(protEMBLCDS); + ncMap.setMap(pmap); + if (map.getTo() != null) + { + dna.addDBRef(ncMap); + } + } + } } } diff --git a/src/jalview/ext/jmol/JalviewJmolBinding.java b/src/jalview/ext/jmol/JalviewJmolBinding.java index 18b04ec..68cc792 100644 --- a/src/jalview/ext/jmol/JalviewJmolBinding.java +++ b/src/jalview/ext/jmol/JalviewJmolBinding.java @@ -43,7 +43,6 @@ import java.awt.event.ComponentListener; import java.io.File; import java.net.URL; import java.security.AccessControlException; -import java.util.Enumeration; import java.util.Hashtable; import java.util.Map; import java.util.Vector; @@ -1328,17 +1327,15 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel return; } - String res; int index; Color col; jmolHistory(false); // TODO: Switch between nucleotide or aa selection expressions - Enumeration en = ResidueProperties.aa3Hash.keys(); - StringBuffer command = new StringBuffer("select *;color white;"); - while (en.hasMoreElements()) + StringBuilder command = new StringBuilder(128); + command.append("select *;color white;"); + for (String res : ResidueProperties.aa3Hash.keySet()) { - res = en.nextElement().toString(); - index = ((Integer) ResidueProperties.aa3Hash.get(res)).intValue(); + index = ResidueProperties.aa3Hash.get(res).intValue(); if (index > 20) { continue; diff --git a/src/jalview/ext/paradise/Annotate3D.java b/src/jalview/ext/paradise/Annotate3D.java index 80b2ab8..55c3c1d 100644 --- a/src/jalview/ext/paradise/Annotate3D.java +++ b/src/jalview/ext/paradise/Annotate3D.java @@ -23,13 +23,13 @@ package jalview.ext.paradise; import jalview.util.MessageManager; import jalview.ws.HttpClientUtils; +import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; import java.net.URL; import java.util.ArrayList; -import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -37,7 +37,6 @@ import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import org.json.simple.JSONArray; import org.json.simple.JSONObject; -import org.json.simple.JSONStreamAware; import org.json.simple.parser.ContentHandler; import org.json.simple.parser.ParseException; @@ -138,7 +137,8 @@ public class Annotate3D // return processJsonResponseFor(HttpClientUtils.doHttpUrlPost(twoDtoolsURL, // vals)); ArrayList readers = new ArrayList(); - readers.add(HttpClientUtils.doHttpUrlPost(twoDtoolsURL, vals)); + final BufferedReader postResponse = HttpClientUtils.doHttpUrlPost(twoDtoolsURL, vals, 0, 0); + readers.add(postResponse); return readers.iterator(); } diff --git a/src/jalview/ext/rbvi/chimera/ChimeraCommands.java b/src/jalview/ext/rbvi/chimera/ChimeraCommands.java index fa1b7e2..148f252 100644 --- a/src/jalview/ext/rbvi/chimera/ChimeraCommands.java +++ b/src/jalview/ext/rbvi/chimera/ChimeraCommands.java @@ -20,6 +20,13 @@ */ package jalview.ext.rbvi.chimera; +import java.awt.Color; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + import jalview.api.FeatureRenderer; import jalview.api.SequenceRenderer; import jalview.datamodel.AlignmentI; @@ -30,13 +37,6 @@ import jalview.structure.StructureSelectionManager; import jalview.util.ColorUtils; import jalview.util.Comparison; -import java.awt.Color; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - /** * Routines for generating Chimera commands for Jalview/Chimera binding * @@ -121,6 +121,7 @@ public class ChimeraCommands final Map> modelData = colourData.get(model); for (String chain : modelData.keySet()) { + boolean hasChain = !"".equals(chain.trim()); for (int[] range : modelData.get(chain)) { if (!firstPositionForModel) @@ -135,7 +136,10 @@ public class ChimeraCommands { sb.append(range[0]).append("-").append(range[1]); } - sb.append(".").append(chain); + if (hasChain) + { + sb.append(".").append(chain); + } firstPositionForModel = false; } } diff --git a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java index 90751e3..9d1ed43 100644 --- a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java +++ b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java @@ -39,7 +39,6 @@ import jalview.util.MessageManager; import java.awt.Color; import java.util.ArrayList; -import java.util.Enumeration; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -87,8 +86,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel private Map chainFile; - private StringBuffer eval = new StringBuffer(); - public String fileLoadingError; /* @@ -109,6 +106,15 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel private boolean loadedInline; /** + * current set of model filenames loaded + */ + String[] modelFileNames = null; + + String lastMousedOverAtomSpec; + + private List lastReply; + + /** * Open a PDB structure file in Chimera and set up mappings from Jalview. * * We check if the PDB model id is already loaded in Chimera, if so don't @@ -173,16 +179,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel } /** - * current set of model filenames loaded - */ - String[] modelFileNames = null; - - - StringBuffer resetLastRes = new StringBuffer(); - - private List lastReply; - - /** * Constructor * * @param ssm @@ -693,7 +689,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel } AlignmentI alignment = alignmentv.getAlignment(); - for (jalview.structure.StructureMappingcommandSet cpdbbyseq : getColourBySequenceCommands(files, sr, fr, alignment)) + for (jalview.structure.StructureMappingcommandSet cpdbbyseq : getColourBySequenceCommands( + files, sr, fr, alignment)) { for (String command : cpdbbyseq.commands) { @@ -713,10 +710,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel String[] files, SequenceRenderer sr, FeatureRenderer fr, AlignmentI alignment) { - return ChimeraCommands - .getColourBySequenceCommand(getSsm(), files, getSequence(), sr, - fr, - alignment); + return ChimeraCommands.getColourBySequenceCommand(getSsm(), files, + getSequence(), sr, fr, alignment); } /** @@ -740,7 +735,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel } } - + // End StructureListener // ////////////////////////// @@ -843,44 +838,44 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel public abstract SequenceRenderer getSequenceRenderer( AlignmentViewPanel alignment); - // jmol/ssm only + /** + * Construct and send a command to highlight an atom. + * + *
+   * Done by generating a command like (to 'highlight' position 44)
+   *   ~select #0:43.C;select #0:44.C
+   * Note this removes the selection from the previous position.
+   * 
+ */ public void highlightAtom(int atomIndex, int pdbResNum, String chain, String pdbfile) { List cms = chimeraMaps.get(pdbfile); if (cms != null) { - int mdlNum = cms.get(0).getModelNumber(); - - viewerCommandHistory(false); - // viewer.stopListening(); - if (resetLastRes.length() > 0) + StringBuilder sb = new StringBuilder(); + sb.append(" #" + cms.get(0).getModelNumber()); + sb.append(":" + pdbResNum); + if (!chain.equals(" ")) { - eval.setLength(0); - eval.append(resetLastRes.toString() + ";"); + sb.append("." + chain); } + String atomSpec = sb.toString(); - eval.append("display "); // +modelNum - - resetLastRes.setLength(0); - resetLastRes.append("~display "); + StringBuilder command = new StringBuilder(32); + if (lastMousedOverAtomSpec != null) { - eval.append(" #" + (mdlNum)); - resetLastRes.append(" #" + (mdlNum)); + command.append("~show " + lastMousedOverAtomSpec + ";"); } - // complete select string - - eval.append(":" + pdbResNum); - resetLastRes.append(":" + pdbResNum); - if (!chain.equals(" ")) + viewerCommandHistory(false); + command.append("show ").append(atomSpec); + String cmd = command.toString(); + if (cmd.length() > 0) { - eval.append("." + chain); - resetLastRes.append("." + chain); + viewer.sendChimeraCommand(cmd, false); } - - viewer.sendChimeraCommand(eval.toString(), false); viewerCommandHistory(true); - // viewer.startListening(); + this.lastMousedOverAtomSpec = atomSpec; } } @@ -1140,20 +1135,17 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel return; } - String res; int index; Color col; // Chimera expects RBG values in the range 0-1 final double normalise = 255D; viewerCommandHistory(false); // TODO: Switch between nucleotide or aa selection expressions - Enumeration en = ResidueProperties.aa3Hash.keys(); StringBuilder command = new StringBuilder(128); command.append("color white;"); - while (en.hasMoreElements()) + for (String res : ResidueProperties.aa3Hash.keySet()) { - res = en.nextElement().toString(); - index = ((Integer) ResidueProperties.aa3Hash.get(res)).intValue(); + index = ResidueProperties.aa3Hash.get(res).intValue(); if (index > 20) { continue; diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 7e451aa..c7792a5 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -20,17 +20,71 @@ */ package jalview.gui; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.GridLayout; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.print.PageFormat; +import java.awt.print.PrinterJob; +import java.beans.PropertyChangeEvent; +import java.io.File; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Deque; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.List; +import java.util.Set; +import java.util.Vector; + +import javax.swing.JButton; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JEditorPane; +import javax.swing.JInternalFrame; +import javax.swing.JLabel; +import javax.swing.JLayeredPane; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; + import jalview.analysis.AAFrequency; import jalview.analysis.AlignmentSorter; import jalview.analysis.AlignmentUtils; import jalview.analysis.Conservation; import jalview.analysis.CrossRef; -import jalview.analysis.NJTree; +import jalview.analysis.Dna; import jalview.analysis.ParseProperties; import jalview.analysis.SequenceIdMatcher; import jalview.api.AlignViewControllerGuiI; import jalview.api.AlignViewControllerI; +import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; +import jalview.api.SplitContainerI; +import jalview.api.ViewStyleI; import jalview.api.analysis.ScoreModelI; import jalview.bin.Cache; import jalview.commands.CommandI; @@ -53,6 +107,7 @@ import jalview.datamodel.SeqCigar; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; +import jalview.gui.ViewSelectionMenu.ViewSetProvider; import jalview.io.AlignmentProperties; import jalview.io.AnnotationFile; import jalview.io.BioJsHTMLOutput; @@ -86,58 +141,12 @@ import jalview.schemes.TurnColourScheme; import jalview.schemes.UserColourScheme; import jalview.schemes.ZappoColourScheme; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import jalview.ws.jws1.Discoverer; import jalview.ws.jws2.Jws2Discoverer; import jalview.ws.jws2.jabaws2.Jws2Instance; import jalview.ws.seqfetcher.DbSourceProxy; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.GridLayout; -import java.awt.Rectangle; -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.StringSelection; -import java.awt.datatransfer.Transferable; -import java.awt.dnd.DnDConstants; -import java.awt.dnd.DropTargetDragEvent; -import java.awt.dnd.DropTargetDropEvent; -import java.awt.dnd.DropTargetEvent; -import java.awt.dnd.DropTargetListener; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.print.PageFormat; -import java.awt.print.PrinterJob; -import java.beans.PropertyChangeEvent; -import java.io.File; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.List; -import java.util.Vector; - -import javax.swing.JButton; -import javax.swing.JCheckBoxMenuItem; -import javax.swing.JEditorPane; -import javax.swing.JInternalFrame; -import javax.swing.JLabel; -import javax.swing.JLayeredPane; -import javax.swing.JMenu; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JProgressBar; -import javax.swing.JRadioButtonMenuItem; -import javax.swing.JScrollPane; -import javax.swing.SwingUtilities; - /** * DOCUMENT ME! * @@ -148,19 +157,20 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, IProgressIndicator, AlignViewControllerGuiI { - /** DOCUMENT ME!! */ public static final int DEFAULT_WIDTH = 700; - /** DOCUMENT ME!! */ public static final int DEFAULT_HEIGHT = 500; + /* + * The currently displayed panel (selected tabbed view if more than one) + */ public AlignmentPanel alignPanel; AlignViewport viewport; public AlignViewControllerI avc; - Vector alignPanels = new Vector(); + List alignPanels = new ArrayList(); /** * Last format used to load or save alignments in this window @@ -339,7 +349,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, buildSortByAnnotationScoresMenu(); buildTreeMenu(); - if (viewport.wrapAlignment) + if (viewport.getWrapAlignment()) { wrapMenuItem_actionPerformed(null); } @@ -351,6 +361,59 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, addKeyListener(); + final List selviews = new ArrayList(); + final List origview = new ArrayList(); + ViewSelectionMenu vsel = new ViewSelectionMenu("Transfer colours from", + new ViewSetProvider() + { + + @Override + public AlignmentPanel[] getAllAlignmentPanels() + { + origview.clear(); + origview.add(alignPanel); + return Desktop.getAlignmentPanels(null); + } + }, selviews, new ItemListener() + { + + @Override + public void itemStateChanged(ItemEvent e) + { + if (origview.size() > 0) + { + ViewStyleI vs = selviews.get(0).getAlignViewport() + .getViewStyle(); + origview.get(0).getAlignViewport().setViewStyle(vs); + AlignViewportI complement = origview.get(0) + .getAlignViewport().getCodingComplement(); + if (complement != null) + { + AlignFrame af = Desktop.getAlignFrameFor(complement); + if (complement.isNucleotide()) + { + complement.setViewStyle(vs); + vs.setCharWidth(vs.getCharWidth() / 3); + } + else + { + int rw = vs.getCharWidth(); + vs.setCharWidth(rw * 3); + complement.setViewStyle(vs); + vs.setCharWidth(rw); + } + af.alignPanel.updateLayout(); + af.setMenusForViewport(); + } + origview.get(0).updateLayout(); + origview.get(0).setSelected(true); + origview.get(0).alignFrame.setMenusForViewport(); + + } + } + }); + formatMenu.add(vsel); + } /** @@ -365,10 +428,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void setFileName(String file, String format) { fileName = file; - currentFileFormat = format; + setFileFormat(format); reload.setEnabled(true); } + /** + * Add a KeyListener with handlers for various KeyPressed and KeyReleased + * events + */ void addKeyListener() { addKeyListener(new KeyAdapter() @@ -542,7 +609,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, break; } case KeyEvent.VK_PAGE_UP: - if (viewport.wrapAlignment) + if (viewport.getWrapAlignment()) { alignPanel.scrollUp(true); } @@ -553,7 +620,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } break; case KeyEvent.VK_PAGE_DOWN: - if (viewport.wrapAlignment) + if (viewport.getWrapAlignment()) { alignPanel.scrollUp(false); } @@ -597,7 +664,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, avc = new jalview.controller.AlignViewController(this, viewport, alignPanel); - alignPanels.addElement(ap); + alignPanels.add(ap); PaintRefresher.Register(ap, ap.av.getSequenceSetId()); @@ -640,7 +707,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, expandViews.setEnabled(true); gatherViews.setEnabled(true); tabbedPane.setVisible(true); - AlignmentPanel first = (AlignmentPanel) alignPanels.firstElement(); + AlignmentPanel first = alignPanels.get(0); tabbedPane.addTab(first.av.viewName, first); this.getContentPane().add(tabbedPane, BorderLayout.CENTER); } @@ -701,6 +768,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, }).start(); } + /** + * Configure menu items that vary according to whether the alignment is + * nucleotide or protein + * + * @param nucleotide + */ public void setGUINucleotide(boolean nucleotide) { showTranslation.setVisible(nucleotide); @@ -709,16 +782,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, showGroupConservation.setEnabled(!nucleotide); rnahelicesColour.setEnabled(nucleotide); purinePyrimidineColour.setEnabled(nucleotide); - // Remember AlignFrame always starts as protein - // if (!nucleotide) - // { - // showTr - // calculateMenu.remove(calculateMenu.getItemCount() - 2); - // } + showComplementMenuItem.setText(MessageManager + .getString(nucleotide ? "label.protein" : "label.nucleotide")); + setColourSelected(jalview.bin.Cache.getDefault( + nucleotide ? Preferences.DEFAULT_COLOUR_NUC + : Preferences.DEFAULT_COLOUR_PROT, "None")); } /** - * set up menus for the currently viewport. This may be called after any + * set up menus for the current viewport. This may be called after any * operation that affects the data in the current view (selection changed, * etc) to update the menus to reflect the new state. */ @@ -737,17 +809,17 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, void setMenusFromViewport(AlignViewport av) { padGapsMenuitem.setSelected(av.isPadGaps()); - colourTextMenuItem.setSelected(av.showColourText); + colourTextMenuItem.setSelected(av.isShowColourText()); abovePIDThreshold.setSelected(av.getAbovePIDThreshold()); conservationMenuItem.setSelected(av.getConservationSelected()); seqLimits.setSelected(av.getShowJVSuffix()); idRightAlign.setSelected(av.isRightAlignIds()); - centreColumnLabelsMenuItem.setState(av.centreColumnLabels); - renderGapsMenuItem.setSelected(av.renderGaps); - wrapMenuItem.setSelected(av.wrapAlignment); - scaleAbove.setVisible(av.wrapAlignment); - scaleLeft.setVisible(av.wrapAlignment); - scaleRight.setVisible(av.wrapAlignment); + centreColumnLabelsMenuItem.setState(av.isCentreColumnLabels()); + renderGapsMenuItem.setSelected(av.isRenderGaps()); + wrapMenuItem.setSelected(av.getWrapAlignment()); + scaleAbove.setVisible(av.getWrapAlignment()); + scaleLeft.setVisible(av.getWrapAlignment()); + scaleRight.setVisible(av.getWrapAlignment()); annotationPanelMenuItem.setState(av.isShowAnnotation()); /* * Show/hide annotations only enabled if annotation panel is shown @@ -756,8 +828,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, hideAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState()); showAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState()); hideAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState()); - viewBoxesMenuItem.setSelected(av.showBoxes); - viewTextMenuItem.setSelected(av.showText); + viewBoxesMenuItem.setSelected(av.getShowBoxes()); + viewTextMenuItem.setSelected(av.getShowText()); showNonconservedMenuItem.setSelected(av.getShowUnconserved()); showGroupConsensus.setSelected(av.isShowGroupConsensus()); showGroupConservation.setSelected(av.isShowGroupConservation()); @@ -769,10 +841,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, .getGlobalColourScheme())); showSeqFeatures.setSelected(av.isShowSequenceFeatures()); - hiddenMarkers.setState(av.showHiddenMarkers); + hiddenMarkers.setState(av.getShowHiddenMarkers()); applyToAllGroups.setState(av.getColourAppliesToAllGroups()); - showNpFeatsMenuitem.setSelected(av.isShowNpFeats()); - showDbRefsMenuitem.setSelected(av.isShowDbRefs()); + showNpFeatsMenuitem.setSelected(av.isShowNPFeats()); + showDbRefsMenuitem.setSelected(av.isShowDBRefs()); autoCalculate.setSelected(av.autoCalculateConsensus); sortByTree.setSelected(av.sortByTree); listenToViewSelections.setSelected(av.followSelection); @@ -862,7 +934,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void actionPerformed(ActionEvent e) { handler.cancelActivity(id); - us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id); + us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new Object[]{((JLabel) progressPanel.getComponent(0)).getText()}), id); } }); progressPanel.add(cancel, BorderLayout.EAST); @@ -1033,7 +1105,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, if (value == JalviewFileChooser.APPROVE_OPTION) { currentFileFormat = chooser.getSelectedFormat(); - if (currentFileFormat == null) + while (currentFileFormat == null) { JOptionPane .showInternalMessageDialog( @@ -1043,8 +1115,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, MessageManager .getString("label.file_format_not_specified"), JOptionPane.WARNING_MESSAGE); + currentFileFormat = chooser.getSelectedFormat(); value = chooser.showSaveDialog(this); - return; + if (value != JalviewFileChooser.APPROVE_OPTION) + { + return; + } } fileName = chooser.getSelectedFile().getPath(); @@ -1141,7 +1217,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, this.setTitle(file); statusBar.setText(MessageManager.formatMessage( "label.successfully_saved_to_file_in_format", - new String[] + new Object[] { fileName, format })); } catch (Exception ex) { @@ -1154,7 +1230,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, if (!success) { JOptionPane.showInternalMessageDialog(this, MessageManager - .formatMessage("label.couldnt_save_file", new String[] + .formatMessage("label.couldnt_save_file", new Object[] { fileName }), MessageManager .getString("label.error_saving_file"), JOptionPane.WARNING_MESSAGE); @@ -1216,7 +1292,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, viewport.getAlignment(), omitHidden, viewport.getColumnSelection())); Desktop.addInternalFrame(cap, MessageManager.formatMessage( - "label.alignment_output_command", new String[] + "label.alignment_output_command", new Object[] { e.getActionCommand() }), 600, 500); } catch (OutOfMemoryError oom) { @@ -1362,7 +1438,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, // setClosed(true) is called for (int i = 0; i < alignPanels.size(); i++) { - AlignmentPanel ap = (AlignmentPanel) alignPanels.elementAt(i); + AlignmentPanel ap = alignPanels.get(i); ap.closePanel(); } } @@ -1384,22 +1460,17 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } /** - * close alignPanel2 and shuffle tabs appropriately. + * Close the specified panel and close up tabs appropriately. * - * @param alignPanel2 + * @param panelToClose */ - public void closeView(AlignmentPanel alignPanel2) + public void closeView(AlignmentPanel panelToClose) { int index = tabbedPane.getSelectedIndex(); - int closedindex = tabbedPane.indexOfComponent(alignPanel2); - alignPanels.removeElement(alignPanel2); - // Unnecessary - // if (viewport == alignPanel2.av) - // { - // viewport = null; - // } - alignPanel2.closePanel(); - alignPanel2 = null; + int closedindex = tabbedPane.indexOfComponent(panelToClose); + alignPanels.remove(panelToClose); + panelToClose.closePanel(); + panelToClose = null; tabbedPane.removeTabAt(closedindex); tabbedPane.validate(); @@ -1419,12 +1490,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, void updateEditMenuBar() { - if (viewport.historyList.size() > 0) + if (viewport.getHistoryList().size() > 0) { undoMenuItem.setEnabled(true); - CommandI command = viewport.historyList.peek(); + CommandI command = viewport.getHistoryList().peek(); undoMenuItem.setText(MessageManager.formatMessage( - "label.undo_command", new String[] + "label.undo_command", new Object[] { command.getDescription() })); } else @@ -1433,13 +1504,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, undoMenuItem.setText(MessageManager.getString("action.undo")); } - if (viewport.redoList.size() > 0) + if (viewport.getRedoList().size() > 0) { redoMenuItem.setEnabled(true); - CommandI command = viewport.redoList.peek(); + CommandI command = viewport.getRedoList().peek(); redoMenuItem.setText(MessageManager.formatMessage( - "label.redo_command", new String[] + "label.redo_command", new Object[] { command.getDescription() })); } else @@ -1453,8 +1524,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { if (command.getSize() > 0) { - viewport.historyList.push(command); - viewport.redoList.clear(); + viewport.addToHistoryList(command); + viewport.clearRedoList(); updateEditMenuBar(); viewport.updateHiddenColumns(); // viewport.hasHiddenColumns = (viewport.getColumnSelection() != null @@ -1472,11 +1543,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { if (alignPanels != null) { - Enumeration e = alignPanels.elements(); AlignmentI[] als = new AlignmentI[alignPanels.size()]; - for (int i = 0; e.hasMoreElements(); i++) + int i = 0; + for (AlignmentPanel ap : alignPanels) { - als[i] = ((AlignmentPanel) e.nextElement()).av.getAlignment(); + als[i++] = ap.av.getAlignment(); } return als; } @@ -1497,15 +1568,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void undoMenuItem_actionPerformed(ActionEvent e) { - if (viewport.historyList.empty()) + if (viewport.getHistoryList().isEmpty()) { return; } - CommandI command = viewport.historyList.pop(); - viewport.redoList.push(command); + CommandI command = viewport.getHistoryList().pop(); + viewport.addToRedoList(command); command.undoCommand(getViewAlignments()); - AlignViewport originalSource = getOriginatingSource(command); + AlignmentViewport originalSource = getOriginatingSource(command); updateEditMenuBar(); if (originalSource != null) @@ -1535,16 +1606,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void redoMenuItem_actionPerformed(ActionEvent e) { - if (viewport.redoList.size() < 1) + if (viewport.getRedoList().size() < 1) { return; } - CommandI command = viewport.redoList.pop(); - viewport.historyList.push(command); + CommandI command = viewport.getRedoList().pop(); + viewport.addToHistoryList(command); command.doCommand(getViewAlignments()); - AlignViewport originalSource = getOriginatingSource(command); + AlignmentViewport originalSource = getOriginatingSource(command); updateEditMenuBar(); if (originalSource != null) @@ -1566,9 +1637,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } } - AlignViewport getOriginatingSource(CommandI command) + AlignmentViewport getOriginatingSource(CommandI command) { - AlignViewport originalSource = null; + AlignmentViewport originalSource = null; // For sequence removal and addition, we need to fire // the property change event FROM the viewport where the // original alignment was altered @@ -1577,16 +1648,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { EditCommand editCommand = (EditCommand) command; al = editCommand.getAlignment(); - Vector comps = (Vector) PaintRefresher.components.get(viewport + List comps = PaintRefresher.components.get(viewport .getSequenceSetId()); - for (int i = 0; i < comps.size(); i++) + for (Component comp : comps) { - if (comps.elementAt(i) instanceof AlignmentPanel) + if (comp instanceof AlignmentPanel) { - if (al == ((AlignmentPanel) comps.elementAt(i)).av.getAlignment()) + if (al == ((AlignmentPanel) comp).av.getAlignment()) { - originalSource = ((AlignmentPanel) comps.elementAt(i)).av; + originalSource = ((AlignmentPanel) comp).av; break; } } @@ -1629,7 +1700,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, synchronized void slideSequences(boolean right, int size) { - List sg = new Vector(); + List sg = new ArrayList(); if (viewport.cursorMode) { sg.add(viewport.getAlignment().getSequenceAt( @@ -1648,13 +1719,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, return; } - Vector invertGroup = new Vector(); + List invertGroup = new ArrayList(); - for (int i = 0; i < viewport.getAlignment().getHeight(); i++) + for (SequenceI seq : viewport.getAlignment().getSequences()) { - if (!sg.contains(viewport.getAlignment().getSequenceAt(i))) + if (!sg.contains(seq)) { - invertGroup.add(viewport.getAlignment().getSequenceAt(i)); + invertGroup.add(seq); } } @@ -1663,7 +1734,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, SequenceI[] seqs2 = new SequenceI[invertGroup.size()]; for (int i = 0; i < invertGroup.size(); i++) { - seqs2[i] = (SequenceI) invertGroup.elementAt(i); + seqs2[i] = invertGroup.get(i); } SlideSequencesCommand ssc; @@ -1711,11 +1782,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } boolean appendHistoryItem = false; - if (viewport.historyList != null && viewport.historyList.size() > 0 - && viewport.historyList.peek() instanceof SlideSequencesCommand) + Deque historyList = viewport.getHistoryList(); + if (historyList != null + && historyList.size() > 0 + && historyList.peek() instanceof SlideSequencesCommand) { appendHistoryItem = ssc - .appendSlideCommand((SlideSequencesCommand) viewport.historyList + .appendSlideCommand((SlideSequencesCommand) historyList .peek()); } @@ -1791,7 +1864,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, Desktop.jalviewClipboard = new Object[] { seqs, viewport.getAlignment().getDataset(), hiddenColumns }; statusBar.setText(MessageManager.formatMessage( - "label.copied_sequences_to_clipboard", new String[] + "label.copied_sequences_to_clipboard", new Object[] { Integer.valueOf(seqs.length).toString() })); } @@ -2089,7 +2162,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, alignment.getSequences()); if (alignPanels != null) { - for (AlignmentPanel ap : ((Vector) alignPanels)) + for (AlignmentPanel ap : alignPanels) { ap.validateAnnotationDimensions(false); } @@ -2236,15 +2309,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, return; } - List seqs = new ArrayList(sg.getSize()); - SequenceI seq; - for (int i = 0; i < sg.getSize(); i++) - { - seq = sg.getSequenceAt(i); - seqs.add(seq); - } - - // If the cut affects all sequences, warn, remove highlighted columns + /* + * If the cut affects all sequences, warn, remove highlighted columns + */ if (sg.getSize() == viewport.getAlignment().getHeight()) { int confirm = JOptionPane.showConfirmDialog(this, @@ -2261,15 +2328,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, sg.getEndRes() + 1); } - SequenceI[] cut = new SequenceI[seqs.size()]; - for (int i = 0; i < seqs.size(); i++) - { - cut[i] = seqs.get(i); - } + SequenceI[] cut = sg.getSequences() + .toArray(new SequenceI[sg.getSize()]); - /* - * //ADD HISTORY ITEM - */ addHistoryItem(new EditCommand( MessageManager.getString("label.cut_sequences"), Action.CUT, cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1, @@ -2511,7 +2572,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, addHistoryItem(removeGapCols); statusBar.setText(MessageManager.formatMessage( - "label.removed_empty_columns", new String[] + "label.removed_empty_columns", new Object[] { Integer.valueOf(removeGapCols.getSize()).toString() })); // This is to maintain viewport position on first residue @@ -2582,16 +2643,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, .getSequences()); } - // else - { - // if (justifySeqs>0) - { - // alignment.justify(justifySeqs!=RIGHT_JUSTIFY); - } - } - - // } - /** * DOCUMENT ME! * @@ -2604,74 +2655,80 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, new Finder(); } - @Override - public void newView_actionPerformed(ActionEvent e) - { - newView(true); - } - - /** - * - * @param copyAnnotation - * if true then duplicate all annnotation, groups and settings - * @return new alignment panel, already displayed. - */ - public AlignmentPanel newView(boolean copyAnnotation) - { - return newView(null, copyAnnotation); - } - /** - * - * @param viewTitle - * title of newly created view - * @return new alignment panel, already displayed. + * Create a new view of the current alignment. */ - public AlignmentPanel newView(String viewTitle) + @Override + public void newView_actionPerformed(ActionEvent e) { - return newView(viewTitle, true); + newView(null, true); } /** + * Creates and shows a new view of the current alignment. * * @param viewTitle - * title of newly created view + * title of newly created view; if null, one will be generated * @param copyAnnotation * if true then duplicate all annnotation, groups and settings * @return new alignment panel, already displayed. */ public AlignmentPanel newView(String viewTitle, boolean copyAnnotation) { + /* + * Create a new AlignmentPanel (with its own, new Viewport) + */ AlignmentPanel newap = new Jalview2XML().copyAlignPanel(alignPanel, true); if (!copyAnnotation) { - // just remove all the current annotation except for the automatic stuff + /* + * remove all groups and annotation except for the automatic stuff + */ newap.av.getAlignment().deleteAllGroups(); - for (AlignmentAnnotation alan : newap.av.getAlignment() - .getAlignmentAnnotation()) - { - if (!alan.autoCalculated) - { - newap.av.getAlignment().deleteAnnotation(alan); - } - ; - } + newap.av.getAlignment().deleteAllAnnotations(false); } - newap.av.gatherViewsHere = false; + newap.av.setGatherViewsHere(false); if (viewport.viewName == null) { - viewport.viewName = "Original"; + viewport.viewName = MessageManager + .getString("label.view_name_original"); } - newap.av.historyList = viewport.historyList; - newap.av.redoList = viewport.redoList; + /* + * Views share the same edits, undo and redo stacks, mappings. + */ + newap.av.setHistoryList(viewport.getHistoryList()); + newap.av.setRedoList(viewport.getRedoList()); + newap.av.getAlignment().setCodonFrames( + viewport.getAlignment().getCodonFrames()); + + newap.av.viewName = getNewViewName(viewTitle); + addAlignmentPanel(newap, true); + newap.alignmentChanged(); + + if (alignPanels.size() == 2) + { + viewport.setGatherViewsHere(true); + } + tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1); + return newap; + } + + /** + * Make a new name for the view, ensuring it is unique within the current + * sequenceSetId. (This used to be essential for Jalview Project archives, but + * these now use viewId. Unique view names are still desirable for usability.) + * + * @param viewTitle + * @return + */ + protected String getNewViewName(String viewTitle) + { int index = Desktop.getViewCount(viewport.getSequenceSetId()); - // make sure the new view has a unique name - this is essential for Jalview - // 2 archives boolean addFirstIndex = false; if (viewTitle == null || viewTitle.trim().length() == 0) { @@ -2683,45 +2740,55 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, index = 1;// we count from 1 if given a specific name } String newViewName = viewTitle + ((addFirstIndex) ? " " + index : ""); - Vector comps = (Vector) PaintRefresher.components.get(viewport + + List comps = PaintRefresher.components.get(viewport .getSequenceSetId()); - Vector existingNames = new Vector(); - for (int i = 0; i < comps.size(); i++) - { - if (comps.elementAt(i) instanceof AlignmentPanel) - { - AlignmentPanel ap = (AlignmentPanel) comps.elementAt(i); - if (!existingNames.contains(ap.av.viewName)) - { - existingNames.addElement(ap.av.viewName); - } - } - } + + List existingNames = getExistingViewNames(comps); while (existingNames.contains(newViewName)) { newViewName = viewTitle + " " + (++index); } + return newViewName; + } - newap.av.viewName = newViewName; - - addAlignmentPanel(newap, true); - newap.alignmentChanged(); - - if (alignPanels.size() == 2) + /** + * Returns a list of distinct view names found in the given list of + * components. View names are held on the viewport of an AlignmentPanel. + * + * @param comps + * @return + */ + protected List getExistingViewNames(List comps) + { + List existingNames = new ArrayList(); + for (Component comp : comps) { - viewport.gatherViewsHere = true; + if (comp instanceof AlignmentPanel) + { + AlignmentPanel ap = (AlignmentPanel) comp; + if (!existingNames.contains(ap.av.viewName)) + { + existingNames.add(ap.av.viewName); + } + } } - tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1); - return newap; + return existingNames; } + /** + * Explode tabbed views into separate windows. + */ @Override public void expandViews_actionPerformed(ActionEvent e) { Desktop.instance.explodeViews(this); } + /** + * Gather views in separate windows back into a tabbed presentation. + */ @Override public void gatherViews_actionPerformed(ActionEvent e) { @@ -2766,7 +2833,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public void centreColumnLabels_actionPerformed(ActionEvent e) { - viewport.centreColumnLabels = centreColumnLabelsMenuItem.getState(); + viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState()); alignPanel.paintAlignment(true); } @@ -2778,6 +2845,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void followHighlight_actionPerformed() { + /* + * Set the 'follow' flag on the Viewport (and scroll to position if now + * true). + */ if (viewport.followHighlight = this.followHighlightMenuItem.getState()) { alignPanel.scrollToPosition( @@ -2811,7 +2882,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, scaleLeft.setVisible(wrapMenuItem.isSelected()); scaleRight.setVisible(wrapMenuItem.isSelected()); viewport.setWrapAlignment(wrapMenuItem.isSelected()); - alignPanel.setWrapAlignment(wrapMenuItem.isSelected()); + alignPanel.updateLayout(); } @Override @@ -2831,7 +2902,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void hideSelSequences_actionPerformed(ActionEvent e) { viewport.hideAllSelectedSeqs(); - alignPanel.paintAlignment(true); +// alignPanel.paintAlignment(true); } /** @@ -3115,11 +3186,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { final boolean setVisible = annotationPanelMenuItem.isSelected(); viewport.setShowAnnotation(setVisible); - alignPanel.setAnnotationVisible(setVisible); this.showAllSeqAnnotations.setEnabled(setVisible); this.hideAllSeqAnnotations.setEnabled(setVisible); this.showAllAlAnnotations.setEnabled(setVisible); this.hideAllAlAnnotations.setEnabled(setVisible); + alignPanel.updateLayout(); } @Override @@ -3130,13 +3201,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, StringBuffer contents = new AlignmentProperties(viewport.getAlignment()) .formatAsHtml(); editPane.setText(MessageManager.formatMessage("label.html_content", - new String[] + new Object[] { contents.toString() })); JInternalFrame frame = new JInternalFrame(); frame.getContentPane().add(new JScrollPane(editPane)); - Desktop.instance.addInternalFrame(frame, MessageManager.formatMessage( - "label.alignment_properties", new String[] + Desktop.addInternalFrame(frame, MessageManager.formatMessage( + "label.alignment_properties", new Object[] { getTitle() }), 500, 400); } @@ -3158,7 +3229,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, OverviewPanel overview = new OverviewPanel(alignPanel); frame.setContentPane(overview); Desktop.addInternalFrame(frame, MessageManager.formatMessage( - "label.overview_params", new String[] + "label.overview_params", new Object[] { this.getTitle() }), frame.getWidth(), frame.getHeight()); frame.pack(); frame.setLayer(JLayeredPane.PALETTE_LAYER); @@ -3361,11 +3432,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { threshold = SliderPanel.setPIDSliderSource(alignPanel, cs, "Background"); - cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus()); + cs.setThreshold(threshold, viewport.isIgnoreGapsConsensus()); } else { - cs.setThreshold(0, viewport.getIgnoreGapsConsensus()); + cs.setThreshold(0, viewport.isIgnoreGapsConsensus()); } if (viewport.getConservationSelected()) @@ -3428,7 +3499,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, || cs instanceof PIDColourScheme || cs instanceof Blosum62ColourScheme) { - sg.cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus()); + sg.cs.setThreshold(threshold, viewport.isIgnoreGapsConsensus()); sg.cs.setConsensus(AAFrequency.calculate( sg.getSequences(viewport.getHiddenRepSequences()), @@ -3436,7 +3507,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } else { - sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus()); + sg.cs.setThreshold(0, viewport.isIgnoreGapsConsensus()); } if (viewport.getConservationSelected()) @@ -3565,8 +3636,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { Component[] menuItems = colourMenu.getMenuComponents(); - int i, iSize = menuItems.length; - for (i = 0; i < iSize; i++) + int iSize = menuItems.length; + for (int i = 0; i < iSize; i++) { if (menuItems[i].getName() != null && menuItems[i].getName().equals("USER_DEFINED")) @@ -3827,7 +3898,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e) { - NewTreePanel("AV", "PID", "Average distance tree using PID"); + newTreePanel("AV", "PID", "Average distance tree using PID"); } /** @@ -3839,7 +3910,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public void neighbourTreeMenuItem_actionPerformed(ActionEvent e) { - NewTreePanel("NJ", "PID", "Neighbour joining tree using PID"); + newTreePanel("NJ", "PID", "Neighbour joining tree using PID"); } /** @@ -3851,7 +3922,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e) { - NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62"); + newTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62"); } /** @@ -3863,7 +3934,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e) { - NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62"); + newTreePanel("AV", "BL", "Average distance tree using BLOSUM62"); } /** @@ -3876,7 +3947,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, * @param title * DOCUMENT ME! */ - void NewTreePanel(String type, String pwType, String title) + void newTreePanel(String type, String pwType, String title) { TreePanel tp; @@ -3967,7 +4038,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void addSortByOrderMenuItem(String title, final AlignmentOrder order) { - final JMenuItem item = new JMenuItem(MessageManager.formatMessage("action.by_title_param", new String[]{title})); + final JMenuItem item = new JMenuItem(MessageManager.formatMessage("action.by_title_param", new Object[]{title})); sort.add(item); item.addActionListener(new java.awt.event.ActionListener() { @@ -4091,7 +4162,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { String treecalcnm = MessageManager.getString("label.tree_calc_" + type.toLowerCase()); - for (final Object pwtype : ResidueProperties.scoreMatrices.keySet()) + for (final String pwtype : ResidueProperties.scoreMatrices.keySet()) { JMenuItem tm = new JMenuItem(); ScoreModelI sm = ResidueProperties.scoreMatrices.get(pwtype); @@ -4107,7 +4178,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public void actionPerformed(ActionEvent e) { - NewTreePanel(type, (String) pwtype, title); + newTreePanel(type, pwtype, title); } }); calculateTree.add(tm); @@ -4117,21 +4188,18 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } sortByTreeMenu.removeAll(); - Vector comps = (Vector) PaintRefresher.components.get(viewport + List comps = PaintRefresher.components.get(viewport .getSequenceSetId()); - Vector treePanels = new Vector(); - int i, iSize = comps.size(); - for (i = 0; i < iSize; i++) + List treePanels = new ArrayList(); + for (Component comp : comps) { - if (comps.elementAt(i) instanceof TreePanel) + if (comp instanceof TreePanel) { - treePanels.add(comps.elementAt(i)); + treePanels.add((TreePanel) comp); } } - iSize = treePanels.size(); - - if (iSize < 1) + if (treePanels.size() < 1) { sortByTreeMenu.setVisible(false); return; @@ -4139,17 +4207,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, sortByTreeMenu.setVisible(true); - for (i = 0; i < treePanels.size(); i++) + for (final TreePanel tp : treePanels) { - final TreePanel tp = (TreePanel) treePanels.elementAt(i); final JMenuItem item = new JMenuItem(tp.getTitle()); - final NJTree tree = ((TreePanel) treePanels.elementAt(i)).getTree(); item.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(ActionEvent e) { - tp.sortByTree_actionPerformed(null); + tp.sortByTree_actionPerformed(); addHistoryItem(tp.sortAlignmentIn(alignPanel)); } @@ -4257,7 +4323,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, * DOCUMENT ME! */ @Override - protected void LoadtreeMenuItem_actionPerformed(ActionEvent e) + protected void loadTreeMenuItem_actionPerformed(ActionEvent e) { // Pick the tree file JalviewFileChooser chooser = new JalviewFileChooser( @@ -4389,7 +4455,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } catch (Exception e) { } - ; } final AlignFrame me = this; buildingMenu = true; @@ -4544,14 +4609,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, .debug("Exception during web service menu building process.", e); } - ; } }); } catch (Exception e) { } - ; - buildingMenu = false; } }).start(); @@ -4663,7 +4725,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void actionPerformed(ActionEvent e) { // TODO: new thread for this call with vis-delay - af.showProductsFor(af.viewport.getSequenceSelection(), ds, + af.showProductsFor(af.viewport.getSequenceSelection(), isRegSel, dna, source); } @@ -4682,14 +4744,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, return showp; } - protected void showProductsFor(SequenceI[] sel, Alignment ds, - boolean isRegSel, boolean dna, String source) + protected void showProductsFor(final SequenceI[] sel, + final boolean isRegSel, final boolean dna, final String source) { - final boolean fisRegSel = isRegSel; - final boolean fdna = dna; - final String fsrc = source; - final AlignFrame ths = this; - final SequenceI[] fsel = sel; Runnable foo = new Runnable() { @@ -4697,15 +4754,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void run() { final long sttime = System.currentTimeMillis(); - ths.setProgressBar(MessageManager.formatMessage("status.searching_for_sequences_from", new String[]{fsrc}), sttime); + AlignFrame.this.setProgressBar(MessageManager.formatMessage( + "status.searching_for_sequences_from", new Object[] + { source }), sttime); try { - Alignment ds = ths.getViewport().getAlignment().getDataset(); // update - // our local - // dataset - // reference + // update our local dataset reference + Alignment ds = AlignFrame.this.getViewport().getAlignment() + .getDataset(); Alignment prods = CrossRef - .findXrefSequences(fsel, fdna, fsrc, ds); + .findXrefSequences(sel, dna, source, ds); if (prods != null) { SequenceI[] sprods = new SequenceI[prods.getHeight()]; @@ -4721,25 +4779,47 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, sprods[s].updatePDBIds(); } Alignment al = new Alignment(sprods); - AlignedCodonFrame[] cf = prods.getCodonFrames(); + Set cf = prods.getCodonFrames(); al.setDataset(ds); - for (int s = 0; cf != null && s < cf.length; s++) + for (AlignedCodonFrame acf : cf) { - al.addCodonFrame(cf[s]); - cf[s] = null; + al.addCodonFrame(acf); } AlignFrame naf = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT); - String newtitle = "" + ((fdna) ? "Proteins " : "Nucleotides ") - + " for " + ((fisRegSel) ? "selected region of " : "") + String newtitle = "" + ((dna) ? "Proteins" : "Nucleotides") + + " for " + ((isRegSel) ? "selected region of " : "") + getTitle(); - Desktop.addInternalFrame(naf, newtitle, DEFAULT_WIDTH, - DEFAULT_HEIGHT); + naf.setTitle(newtitle); + + // remove this flag once confirmed we want a split view + boolean asSplitFrame = true; + if (asSplitFrame) + { + final Alignment copyAlignment = new Alignment(new Alignment( + AlignFrame.this.viewport.getSequenceSelection())); + AlignFrame copyThis = new AlignFrame(copyAlignment, + AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); + copyThis.setTitle(AlignFrame.this.getTitle()); + // SplitFrame with dna above, protein below + SplitFrame sf = new SplitFrame(dna ? copyThis : naf, + dna ? naf : copyThis); + naf.setVisible(true); + copyThis.setVisible(true); + String linkedTitle = MessageManager + .getString("label.linked_view_title"); + Desktop.addInternalFrame(sf, linkedTitle, -1, -1); + } + else + { + Desktop.addInternalFrame(naf, newtitle, DEFAULT_WIDTH, + DEFAULT_HEIGHT); + } } else { System.err.println("No Sequences generated for xRef type " - + fsrc); + + source); } } catch (Exception e) { @@ -4753,7 +4833,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, jalview.bin.Cache.log.error("Error when finding crossreferences", e); } - ths.setProgressBar(MessageManager.formatMessage("status.finished_searching_for_sequences_from", new String[]{fsrc}), + AlignFrame.this.setProgressBar(MessageManager.formatMessage( + "status.finished_searching_for_sequences_from", + new Object[] + { source }), sttime); } @@ -4779,96 +4862,66 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } } - @Override - public void showProducts_actionPerformed(ActionEvent e) - { - // ///////////////////////////// - // Collect Data to be translated/transferred - - SequenceI[] selection = viewport.getSequenceSelection(); - AlignmentI al = null; - try - { - al = jalview.analysis.Dna.CdnaTranslate(selection, viewport - .getViewAsVisibleContigs(true), viewport.getGapCharacter(), - viewport.getAlignment().getDataset()); - } catch (Exception ex) - { - al = null; - jalview.bin.Cache.log.debug("Exception during translation.", ex); - } - if (al == null) - { - JOptionPane - .showMessageDialog( - Desktop.desktop, - MessageManager - .getString("label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation"), - MessageManager.getString("label.translation_failed"), - JOptionPane.WARNING_MESSAGE); - } - else - { - AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT); - Desktop.addInternalFrame(af, MessageManager.formatMessage( - "label.translation_of_params", new String[] - { this.getTitle() }), DEFAULT_WIDTH, DEFAULT_HEIGHT); - } - } - + /** + * Construct and display a new frame containing the translation of this + * frame's DNA sequences to their aligned protein (amino acid) equivalents. + */ @Override public void showTranslation_actionPerformed(ActionEvent e) { - // ///////////////////////////// - // Collect Data to be translated/transferred - - SequenceI[] selection = viewport.getSequenceSelection(); - String[] seqstring = viewport.getViewAsString(true); AlignmentI al = null; try { - al = jalview.analysis.Dna.CdnaTranslate(selection, seqstring, - viewport.getViewAsVisibleContigs(true), viewport - .getGapCharacter(), viewport.getAlignment() - .getAlignmentAnnotation(), viewport.getAlignment() - .getWidth(), viewport.getAlignment().getDataset()); + Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true)); + + al = dna.translateCdna(); } catch (Exception ex) { - al = null; jalview.bin.Cache.log.error( "Exception during translation. Please report this !", ex); - JOptionPane - .showMessageDialog( - Desktop.desktop, - MessageManager - .getString("label.error_when_translating_sequences_submit_bug_report"), - MessageManager - .getString("label.implementation_error") - + MessageManager - .getString("translation_failed"), - JOptionPane.ERROR_MESSAGE); + final String msg = MessageManager + .getString("label.error_when_translating_sequences_submit_bug_report"); + final String title = MessageManager + .getString("label.implementation_error") + + MessageManager.getString("translation_failed"); + JOptionPane.showMessageDialog(Desktop.desktop, msg, title, + JOptionPane.ERROR_MESSAGE); return; } - if (al == null) + if (al == null || al.getHeight() == 0) { - JOptionPane - .showMessageDialog( - Desktop.desktop, - MessageManager - .getString("label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation"), - MessageManager.getString("label.translation_failed"), - JOptionPane.WARNING_MESSAGE); + final String msg = MessageManager + .getString("label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation"); + final String title = MessageManager + .getString("label.translation_failed"); + JOptionPane.showMessageDialog(Desktop.desktop, msg, title, + JOptionPane.WARNING_MESSAGE); } else { AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT); - Desktop.addInternalFrame(af, MessageManager.formatMessage( - "label.translation_of_params", new String[] - { this.getTitle() }), DEFAULT_WIDTH, DEFAULT_HEIGHT); + af.setFileFormat(this.currentFileFormat); + final String newTitle = MessageManager.formatMessage( + "label.translation_of_params", new Object[] + { this.getTitle() }); + af.setTitle(newTitle); + final SequenceI[] seqs = viewport.getSelectionAsNewSequence(); + viewport.openSplitFrame(af, new Alignment(seqs), al.getCodonFrames()); + // Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH, DEFAULT_HEIGHT); } } /** + * Set the file format + * + * @param fileFormat + */ + public void setFileFormat(String fileFormat) + { + this.currentFileFormat = fileFormat; + } + + /** * Try to load a features file onto the alignment. * * @param file @@ -5060,7 +5113,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, MessageManager .formatMessage( "label.automatically_associate_pdb_files_with_sequences_same_name", - new String[] + new Object[] { Integer.valueOf( filesmatched .size()) @@ -5103,7 +5156,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, ""+MessageManager .formatMessage( "label.ignore_unmatched_dropped_files_info", - new String[] + new Object[] { Integer.valueOf( filesnotmatched .size()) @@ -5211,7 +5264,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { jalview.io.JPredFile predictions = new jalview.io.JPredFile( file, protocol); - new JnetAnnotationMaker().add_annotation(predictions, + new JnetAnnotationMaker(); + JnetAnnotationMaker.add_annotation(predictions, viewport.getAlignment(), 0, false); SequenceI repseq = viewport.getAlignment().getSequenceAt(0); viewport.getAlignment().setSeqrep(repseq); @@ -5288,31 +5342,55 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } } + /** + * Method invoked by the ChangeListener on the tabbed pane, in other words + * when a different tabbed pane is selected by the user or programmatically. + */ @Override public void tabSelectionChanged(int index) { if (index > -1) { - alignPanel = (AlignmentPanel) alignPanels.elementAt(index); + alignPanel = alignPanels.get(index); viewport = alignPanel.av; avc.setViewportAndAlignmentPanel(viewport, alignPanel); setMenusFromViewport(viewport); } + + /* + * If there is a frame linked to this one in a SplitPane, switch it to the + * same view tab index. No infinite recursion of calls should happen, since + * tabSelectionChanged() should not get invoked on setting the selected + * index to an unchanged value. Guard against setting an invalid index + * before the new view peer tab has been created. + */ + final AlignViewportI peer = viewport.getCodingComplement(); + if (peer != null) + { + AlignFrame linkedAlignFrame = ((AlignViewport) peer).getAlignPanel().alignFrame; + if (linkedAlignFrame.tabbedPane.getTabCount() > index) + { + linkedAlignFrame.tabbedPane.setSelectedIndex(index); + } + } } + /** + * On right mouse click on view tab, prompt for and set new view name. + */ @Override public void tabbedPane_mousePressed(MouseEvent e) { if (SwingUtilities.isRightMouseButton(e)) { - String reply = JOptionPane.showInternalInputDialog(this, - MessageManager.getString("label.enter_view_name"), - MessageManager.getString("label.enter_view_name"), + String msg = MessageManager.getString("label.enter_view_name"); + String reply = JOptionPane.showInternalInputDialog(this, msg, msg, JOptionPane.QUESTION_MESSAGE); if (reply != null) { viewport.viewName = reply; + // TODO warn if reply is in getExistingViewNames()? tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply); } } @@ -5352,7 +5430,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void showDbRefs_actionPerformed(ActionEvent e) { - viewport.setShowDbRefs(showDbRefsMenuitem.isSelected()); + viewport.setShowDBRefs(showDbRefsMenuitem.isSelected()); } /* @@ -5364,7 +5442,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void showNpFeats_actionPerformed(ActionEvent e) { - viewport.setShowNpFeats(showNpFeatsMenuitem.isSelected()); + viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected()); } /** @@ -5373,7 +5451,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, * * @param av */ - public boolean closeView(AlignViewport av) + public boolean closeView(AlignViewportI av) { if (viewport == av) { @@ -5519,7 +5597,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } }); - fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.fetch_retrieve_from", new String[]{src.getDbName()}))); + fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.fetch_retrieve_from", new Object[]{src.getDbName()}))); dfetch.add(fetchr); comp++; } @@ -5530,7 +5608,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, // fetch all entry DbSourceProxy src = otherdb.get(0); fetchr = new JMenuItem(MessageManager.formatMessage( - "label.fetch_all_param", new String[] + "label.fetch_all_param", new Object[] { src.getDbSource() })); fetchr.addActionListener(new ActionListener() { @@ -5552,11 +5630,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } }); - fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.fetch_retrieve_from_all_sources", new String[]{Integer.valueOf(otherdb.size()).toString(), src.getDbSource(), src.getDbName()}))); + fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.fetch_retrieve_from_all_sources", new Object[]{Integer.valueOf(otherdb.size()).toString(), src.getDbSource(), src.getDbName()}))); dfetch.add(fetchr); comp++; // and then build the rest of the individual menus - ifetch = new JMenu(MessageManager.formatMessage("label.source_from_db_source", new String[]{src.getDbSource()})); + ifetch = new JMenu(MessageManager.formatMessage("label.source_from_db_source", new Object[]{src.getDbSource()})); icomp = 0; String imname = null; int i = 0; @@ -5569,7 +5647,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, 0, 10) + "..." : dbname; if (imname == null) { - imname = MessageManager.formatMessage("label.from_msname", new String[]{sname}); + imname = MessageManager.formatMessage("label.from_msname", new Object[]{sname}); } fetchr = new JMenuItem(msname); final DbSourceProxy[] dassrc = @@ -5596,7 +5674,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, }); fetchr.setToolTipText("" - + MessageManager.formatMessage("label.fetch_retrieve_from", new String[]{dbname})); + + MessageManager.formatMessage("label.fetch_retrieve_from", new Object[]{dbname})); ifetch.add(fetchr); ++i; if (++icomp >= mcomp || i == (otherdb.size())) @@ -5802,7 +5880,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, throw new Error(MessageManager.getString("error.implementation_error_cannot_show_view_alignment_frame")); } if (tabbedPane != null - & alignPanels.indexOf(alignmentPanel) != tabbedPane + && tabbedPane.getTabCount() > 0 + && alignPanels.indexOf(alignmentPanel) != tabbedPane .getSelectedIndex()) { tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel)); @@ -5850,11 +5929,74 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, /** * - * @return alignment panels in this alignemnt frame + * @return alignment panels in this alignment frame + */ + public List getAlignPanels() + { + return alignPanels == null ? Arrays.asList(alignPanel) + : alignPanels; + } + + /** + * Open a new alignment window, with the cDNA associated with this (protein) + * alignment, aligned as is the protein. + */ + protected void viewAsCdna_actionPerformed() + { + // TODO no longer a menu action - refactor as required + final AlignmentI alignment = getViewport().getAlignment(); + Set mappings = alignment.getCodonFrames(); + if (mappings == null) + { + return; + } + List cdnaSeqs = new ArrayList(); + for (SequenceI aaSeq : alignment.getSequences()) { + for (AlignedCodonFrame acf : mappings) { + SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence()); + if (dnaSeq != null) + { + /* + * There is a cDNA mapping for this protein sequence - add to new + * alignment. It will share the same dataset sequence as other mapped + * cDNA (no new mappings need to be created). + */ + final Sequence newSeq = new Sequence(dnaSeq); + newSeq.setDatasetSequence(dnaSeq); + cdnaSeqs.add(newSeq); + } + } + } + if (cdnaSeqs.size() == 0) + { + // show a warning dialog no mapped cDNA + return; + } + AlignmentI cdna = new Alignment(cdnaSeqs.toArray(new SequenceI[cdnaSeqs + .size()])); + AlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + cdna.alignAs(alignment); + String newtitle = "cDNA " + MessageManager.getString("label.for") + " " + + this.title; + Desktop.addInternalFrame(alignFrame, newtitle, + AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + } + + /** + * Set visibility of dna/protein complement view (available when shown in a + * split frame). + * + * @param show */ - public List getAlignPanels() + @Override + protected void showComplement_actionPerformed(boolean show) { - return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels; + SplitContainerI sf = getSplitViewContainer(); + if (sf != null) { + sf.setComplementVisible(this, show); + } } } diff --git a/src/jalview/gui/AlignViewport.java b/src/jalview/gui/AlignViewport.java index b088e08..e4593a3 100644 --- a/src/jalview/gui/AlignViewport.java +++ b/src/jalview/gui/AlignViewport.java @@ -38,11 +38,27 @@ */ package jalview.gui; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.Set; +import java.util.Vector; + +import javax.swing.JInternalFrame; +import javax.swing.JOptionPane; + +import jalview.analysis.AlignmentUtils; import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; import jalview.analysis.NJTree; import jalview.api.AlignViewportI; +import jalview.api.ViewStyleI; import jalview.bin.Cache; import jalview.commands.CommandI; +import jalview.datamodel.AlignedCodonFrame; +import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentI; import jalview.datamodel.ColumnSelection; import jalview.datamodel.PDBEntry; @@ -51,21 +67,14 @@ import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.schemes.ColourSchemeProperty; import jalview.schemes.UserColourScheme; +import jalview.structure.CommandListener; import jalview.structure.SelectionSource; import jalview.structure.StructureSelectionManager; import jalview.structure.VamsasSource; +import jalview.util.MessageManager; import jalview.viewmodel.AlignmentViewport; import jalview.ws.params.AutoCalcSetting; -import java.awt.Color; -import java.awt.Container; -import java.awt.Font; -import java.awt.Rectangle; -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.Stack; -import java.util.Vector; - /** * DOCUMENT ME! * @@ -73,7 +82,7 @@ import java.util.Vector; * @version $Revision: 1.141 $ */ public class AlignViewport extends AlignmentViewport implements - SelectionSource, VamsasSource, AlignViewportI + SelectionSource, AlignViewportI, CommandListener { int startRes; @@ -83,61 +92,26 @@ public class AlignViewport extends AlignmentViewport implements int endSeq; - boolean showJVSuffix = true; - - boolean showText = true; - - boolean showColourText = false; - - boolean showBoxes = true; - - boolean wrapAlignment = false; - - boolean renderGaps = true; - - SequenceAnnotationOrder sortAnnotationsBy = null; - - int charHeight; - - int charWidth; - - boolean validCharWidth; - - int wrappedWidth; - Font font; - boolean seqNameItalics; - NJTree currentTree = null; - boolean scaleAboveWrapped = false; - - boolean scaleLeftWrapped = true; - - boolean scaleRightWrapped = true; - - boolean showHiddenMarkers = true; - boolean cursorMode = false; boolean antiAlias = false; - Rectangle explodedPosition; + private Rectangle explodedGeometry; String viewName; - boolean gatherViewsHere = false; - - Stack historyList = new Stack(); - - Stack redoList = new Stack(); - - int thresholdTextColour = 0; - - Color textColour = Color.black; - - Color textColour2 = Color.white; + /* + * Flag set true on the view that should 'gather' multiple views of the same + * sequence set id when a project is reloaded. Set false on all views when + * they are 'exploded' into separate windows. Set true on the current view + * when 'Gather' is performed, and also on the first tab when the first new + * view is created. + */ + private boolean gatherViewsHere = false; private AnnotationColumnChooser annotationColumnSelectionState; /** @@ -247,32 +221,46 @@ public class AlignViewport extends AlignmentViewport implements init(); } - void init() + private void applyViewProperties() { - this.startRes = 0; - this.endRes = alignment.getWidth() - 1; - this.startSeq = 0; - this.endSeq = alignment.getHeight() - 1; - antiAlias = Cache.getDefault("ANTI_ALIAS", false); - showJVSuffix = Cache.getDefault("SHOW_JVSUFFIX", true); + viewStyle.setShowJVSuffix(Cache.getDefault("SHOW_JVSUFFIX", true)); setShowAnnotation(Cache.getDefault("SHOW_ANNOTATIONS", true)); setRightAlignIds(Cache.getDefault("RIGHT_ALIGN_IDS", false)); - centreColumnLabels = Cache.getDefault("CENTRE_COLUMN_LABELS", false); + setCentreColumnLabels(Cache.getDefault("CENTRE_COLUMN_LABELS", false)); autoCalculateConsensus = Cache.getDefault("AUTO_CALC_CONSENSUS", true); setPadGaps(Cache.getDefault("PAD_GAPS", true)); - shownpfeats = Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true); - showdbrefs = Cache.getDefault("SHOW_DBREFS_TOOLTIP", true); + setShowNPFeats(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true)); + setShowDBRefs(Cache.getDefault("SHOW_DBREFS_TOOLTIP", true)); + viewStyle.setSeqNameItalics(Cache.getDefault("ID_ITALICS", true)); + viewStyle.setWrapAlignment(Cache.getDefault("WRAP_ALIGNMENT", false)); + viewStyle.setShowUnconserved(Cache + .getDefault("SHOW_UNCONSERVED", false)); + sortByTree = Cache.getDefault("SORT_BY_TREE", false); + followSelection = Cache.getDefault("FOLLOW_SELECTIONS", true); + sortAnnotationsBy = SequenceAnnotationOrder.valueOf(Cache.getDefault( + Preferences.SORT_ANNOTATIONS, + SequenceAnnotationOrder.NONE.name())); + showAutocalculatedAbove = Cache.getDefault( + Preferences.SHOW_AUTOCALC_ABOVE, false); + + } + + void init() + { + this.startRes = 0; + this.endRes = alignment.getWidth() - 1; + this.startSeq = 0; + this.endSeq = alignment.getHeight() - 1; + applyViewProperties(); String fontName = Cache.getDefault("FONT_NAME", "SansSerif"); String fontStyle = Cache.getDefault("FONT_STYLE", Font.PLAIN + ""); String fontSize = Cache.getDefault("FONT_SIZE", "10"); - seqNameItalics = Cache.getDefault("ID_ITALICS", true); - int style = 0; if (fontStyle.equals("bold")) @@ -284,7 +272,7 @@ public class AlignViewport extends AlignmentViewport implements style = 2; } - setFont(new Font(fontName, style, Integer.parseInt(fontSize))); + setFont(new Font(fontName, style, Integer.parseInt(fontSize)), true); alignment .setGapCharacter(Cache.getDefault("GAP_SYMBOL", "-").charAt(0)); @@ -309,16 +297,24 @@ public class AlignViewport extends AlignmentViewport implements showConsensus = Cache.getDefault("SHOW_IDENTITY", true); } initAutoAnnotation(); - if (jalview.bin.Cache.getProperty("DEFAULT_COLOUR") != null) + String colourProperty = alignment.isNucleotide() ? Preferences.DEFAULT_COLOUR_NUC + : Preferences.DEFAULT_COLOUR_PROT; + String propertyValue = Cache.getProperty(colourProperty); + if (propertyValue == null) + { + // fall back on this property for backwards compatibility + propertyValue = Cache.getProperty(Preferences.DEFAULT_COLOUR); + } + if (propertyValue != null) { globalColourScheme = ColourSchemeProperty.getColour(alignment, - jalview.bin.Cache.getProperty("DEFAULT_COLOUR")); + propertyValue); if (globalColourScheme instanceof UserColourScheme) { globalColourScheme = UserDefinedColours.loadDefaultColours(); ((UserColourScheme) globalColourScheme).setThreshold(0, - getIgnoreGapsConsensus()); + isIgnoreGapsConsensus()); } if (globalColourScheme != null) @@ -326,31 +322,9 @@ public class AlignViewport extends AlignmentViewport implements globalColourScheme.setConsensus(hconsensus); } } - - wrapAlignment = Cache.getDefault("WRAP_ALIGNMENT", false); - showUnconserved = Cache.getDefault("SHOW_UNCONSERVED", false); - sortByTree = Cache.getDefault("SORT_BY_TREE", false); - followSelection = Cache.getDefault("FOLLOW_SELECTIONS", true); - sortAnnotationsBy = SequenceAnnotationOrder.valueOf(Cache.getDefault( - Preferences.SORT_ANNOTATIONS, - SequenceAnnotationOrder.NONE.name())); - showAutocalculatedAbove = Cache.getDefault( - Preferences.SHOW_AUTOCALC_ABOVE, false); } /** - * centre columnar annotation labels in displayed alignment annotation TODO: - * add to jalviewXML and annotation display settings - */ - boolean centreColumnLabels = false; - - private boolean showdbrefs; - - private boolean shownpfeats; - - // --------END Structure Conservation - - /** * get the consensus sequence as displayed under the PID consensus annotation * row. * @@ -494,105 +468,52 @@ public class AlignViewport extends AlignmentViewport implements return endSeq; } + boolean validCharWidth; + /** - * DOCUMENT ME! + * update view settings with the given font. You may need to call + * alignPanel.fontChanged to update the layout geometry * - * @param f - * DOCUMENT ME! + * @param setGrid + * when true, charWidth/height is set according to font mentrics */ - public void setFont(Font f) + public void setFont(Font f, boolean setGrid) { font = f; Container c = new Container(); java.awt.FontMetrics fm = c.getFontMetrics(font); - setCharHeight(fm.getHeight()); - setCharWidth(fm.charWidth('M')); - validCharWidth = true; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public Font getFont() - { - return font; - } - - /** - * DOCUMENT ME! - * - * @param w - * DOCUMENT ME! - */ - public void setCharWidth(int w) - { - this.charWidth = w; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public int getCharWidth() - { - return charWidth; - } - - /** - * DOCUMENT ME! - * - * @param h - * DOCUMENT ME! - */ - public void setCharHeight(int h) - { - this.charHeight = h; - } + int w = viewStyle.getCharWidth(), ww = fm.charWidth('M'), h = viewStyle + .getCharHeight(); + if (setGrid) + { + setCharHeight(fm.getHeight()); + setCharWidth(ww); + } + viewStyle.setFontName(font.getName()); + viewStyle.setFontStyle(font.getStyle()); + viewStyle.setFontSize(font.getSize()); - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public int getCharHeight() - { - return charHeight; + validCharWidth = true; } - /** - * DOCUMENT ME! - * - * @param w - * DOCUMENT ME! - */ - public void setWrappedWidth(int w) + @Override + public void setViewStyle(ViewStyleI settingsForView) { - this.wrappedWidth = w; - } + super.setViewStyle(settingsForView); + setFont(new Font(viewStyle.getFontName(), viewStyle.getFontStyle(), + viewStyle.getFontSize()), false); - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public int getWrappedWidth() - { - return wrappedWidth; } - /** * DOCUMENT ME! * * @return DOCUMENT ME! */ - public AlignmentI getAlignment() + public Font getFont() { - return alignment; + return font; } /** @@ -619,101 +540,6 @@ public class AlignViewport extends AlignmentViewport implements /** * DOCUMENT ME! * - * @param state - * DOCUMENT ME! - */ - public void setWrapAlignment(boolean state) - { - wrapAlignment = state; - } - - /** - * DOCUMENT ME! - * - * @param state - * DOCUMENT ME! - */ - public void setShowText(boolean state) - { - showText = state; - } - - /** - * DOCUMENT ME! - * - * @param state - * DOCUMENT ME! - */ - public void setRenderGaps(boolean state) - { - renderGaps = state; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean getColourText() - { - return showColourText; - } - - /** - * DOCUMENT ME! - * - * @param state - * DOCUMENT ME! - */ - public void setColourText(boolean state) - { - showColourText = state; - } - - /** - * DOCUMENT ME! - * - * @param state - * DOCUMENT ME! - */ - public void setShowBoxes(boolean state) - { - showBoxes = state; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean getWrapAlignment() - { - return wrapAlignment; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean getShowText() - { - return showText; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean getShowBoxes() - { - return showBoxes; - } - - /** - * DOCUMENT ME! - * * @return DOCUMENT ME! */ public char getGapCharacter() @@ -767,110 +593,6 @@ public class AlignViewport extends AlignmentViewport implements } /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean getShowJVSuffix() - { - return showJVSuffix; - } - - /** - * DOCUMENT ME! - * - * @param b - * DOCUMENT ME! - */ - public void setShowJVSuffix(boolean b) - { - showJVSuffix = b; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean getScaleAboveWrapped() - { - return scaleAboveWrapped; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean getScaleLeftWrapped() - { - return scaleLeftWrapped; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public boolean getScaleRightWrapped() - { - return scaleRightWrapped; - } - - /** - * DOCUMENT ME! - * - * @param b - * DOCUMENT ME! - */ - public void setScaleAboveWrapped(boolean b) - { - scaleAboveWrapped = b; - } - - /** - * DOCUMENT ME! - * - * @param b - * DOCUMENT ME! - */ - public void setScaleLeftWrapped(boolean b) - { - scaleLeftWrapped = b; - } - - /** - * DOCUMENT ME! - * - * @param b - * DOCUMENT ME! - */ - public void setScaleRightWrapped(boolean b) - { - scaleRightWrapped = b; - } - - public void setDataset(boolean b) - { - isDataset = b; - } - - public boolean isDataset() - { - return isDataset; - } - - public boolean getShowHiddenMarkers() - { - return showHiddenMarkers; - } - - public void setShowHiddenMarkers(boolean show) - { - showHiddenMarkers = show; - } - - /** * returns the visible column regions of the alignment * * @param selectedRegionOnly @@ -943,55 +665,6 @@ public class AlignViewport extends AlignmentViewport implements return false; } - public boolean getCentreColumnLabels() - { - return centreColumnLabels; - } - - public void setCentreColumnLabels(boolean centrecolumnlabels) - { - centreColumnLabels = centrecolumnlabels; - } - - /** - * enable or disable the display of Database Cross References in the sequence - * ID tooltip - */ - public void setShowDbRefs(boolean show) - { - showdbrefs = show; - } - - /** - * - * @return true if Database References are to be displayed on tooltips. - */ - public boolean isShowDbRefs() - { - return showdbrefs; - } - - /** - * - * @return true if Non-positional features are to be displayed on tooltips. - */ - public boolean isShowNpFeats() - { - return shownpfeats; - } - - /** - * enable or disable the display of Non-Positional sequence features in the - * sequence ID tooltip - * - * @param show - */ - public void setShowNpFeats(boolean show) - { - shownpfeats = show; - } - - /** * when set, view will scroll to show the highlighted position */ @@ -1018,6 +691,9 @@ public class AlignViewport extends AlignmentViewport implements return followSelection; } + /** + * Send the current selection to be broadcast to any selection listeners. + */ public void sendSelection() { jalview.structure.StructureSelectionManager @@ -1038,7 +714,6 @@ public class AlignViewport extends AlignmentViewport implements { AlignmentPanel[] aps = PaintRefresher.getAssociatedPanels(this .getSequenceSetId()); - AlignmentPanel ap = null; for (int p = 0; aps != null && p < aps.length; p++) { if (aps[p].av == this) @@ -1092,6 +767,10 @@ public class AlignViewport extends AlignmentViewport implements } } + /** + * Returns the (Desktop) instance of the StructureSelectionManager + */ + @Override public StructureSelectionManager getStructureSelectionManager() { return StructureSelectionManager @@ -1159,8 +838,6 @@ public class AlignViewport extends AlignmentViewport implements private Hashtable calcIdParams = new Hashtable(); - private boolean showAutocalculatedAbove; - public AutoCalcSetting getCalcIdSettingsFor(String calcId) { return calcIdParams.get(calcId); @@ -1179,24 +856,229 @@ public class AlignViewport extends AlignmentViewport implements } } - protected SequenceAnnotationOrder getSortAnnotationsBy() - { - return sortAnnotationsBy; + /** + * Method called when another alignment's edit (or possibly other) command is + * broadcast to here. + * + * To allow for sequence mappings (e.g. protein to cDNA), we have to first + * 'unwind' the command on the source sequences (in simulation, not in fact), + * and then for each edit in turn: + *
    + *
  • compute the equivalent edit on the mapped sequences
  • + *
  • apply the mapped edit
  • + *
  • 'apply' the source edit to the working copy of the source sequences
  • + *
+ * + * @param command + * @param undo + * @param ssm + */ + @Override + public void mirrorCommand(CommandI command, boolean undo, + StructureSelectionManager ssm, VamsasSource source) + { + /* + * Do nothing unless we are a 'complement' of the source. May replace this + * with direct calls not via SSM. + */ + if (source instanceof AlignViewportI + && ((AlignViewportI) source).getCodingComplement() == this) + { + // ok to continue; + } + else + { + return; + } + + CommandI mappedCommand = ssm.mapCommand(command, undo, getAlignment(), + getGapCharacter()); + if (mappedCommand != null) + { + AlignmentI[] views = getAlignPanel().alignFrame.getViewAlignments(); + mappedCommand.doCommand(views); + getAlignPanel().alignmentChanged(); + } } - protected void setSortAnnotationsBy(SequenceAnnotationOrder sortAnnotationsBy) + /** + * Add the sequences from the given alignment to this viewport. Optionally, + * may give the user the option to open a new frame, or split panel, with cDNA + * and protein linked. + * + * @param al + * @param title + */ + public void addAlignment(AlignmentI al, String title) { - this.sortAnnotationsBy = sortAnnotationsBy; + // TODO: promote to AlignViewportI? applet CutAndPasteTransfer is different + + // JBPComment: title is a largely redundant parameter at the moment + // JBPComment: this really should be an 'insert/pre/append' controller + // JBPComment: but the DNA/Protein check makes it a bit more complex + + // refactored from FileLoader / CutAndPasteTransfer / SequenceFetcher with + // this comment: + // TODO: create undo object for this JAL-1101 + + /* + * If one alignment is protein and one nucleotide, with at least one + * sequence name in common, offer to open a linked alignment. + */ + if (AlignmentUtils.isMappable(al, getAlignment())) + { + if (openLinkedAlignment(al, title)) + { + return; + } + } + // TODO: JAL-407 regardless of above - identical sequences (based on ID and + // provenance) should share the same dataset sequence + + for (int i = 0; i < al.getHeight(); i++) + { + getAlignment().addSequence(al.getSequenceAt(i)); + } + // TODO this call was done by SequenceFetcher but not FileLoader or + // CutAndPasteTransfer. Is it needed? + // JBPComment: this repositions the view to show the new sequences + // JBPComment: so it is needed for UX + setEndSeq(getAlignment().getHeight()); + firePropertyChange("alignment", null, getAlignment().getSequences()); } - protected boolean isShowAutocalculatedAbove() - { - return showAutocalculatedAbove; + /** + * Show a dialog with the option to open and link (cDNA <-> protein) as a new + * alignment. Returns true if the new alignment was opened, false if not, + * because the user declined the offer. + * + * @param title + */ + protected boolean openLinkedAlignment(AlignmentI al, String title) + { + String[] options = new String[] + { MessageManager.getString("action.no"), + MessageManager.getString("label.split_window"), + MessageManager.getString("label.new_window"), }; + final String question = JvSwingUtils.wrapTooltip(true, + MessageManager.getString("label.open_split_window?")); + int response = JOptionPane.showOptionDialog(Desktop.desktop, question, + MessageManager.getString("label.open_split_window"), + JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, + options, options[0]); + + if (response != 1 && response != 2) + { + return false; + } + final boolean openSplitPane = (response == 1); + final boolean openInNewWindow = (response == 2); + + /* + * Create the AlignFrame first (which creates the new alignment's datasets), + * before attempting sequence mapping. + */ + AlignFrame newAlignFrame = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + newAlignFrame.setTitle(title); + + /* + * Identify protein and dna alignments. Make a copy of this one if opening + * in a new split pane. + */ + AlignmentI thisAlignment = openSplitPane ? new Alignment(getAlignment()) + : getAlignment(); + AlignmentI protein = al.isNucleotide() ? thisAlignment : al; + final AlignmentI cdna = al.isNucleotide() ? al : thisAlignment; + + newAlignFrame.statusBar.setText(MessageManager.formatMessage( + "label.successfully_loaded_file", new Object[] + { title })); + + // TODO if we want this (e.g. to enable reload of the alignment from file), + // we will need to add parameters to the stack. + // if (!protocol.equals(AppletFormatAdapter.PASTE)) + // { + // alignFrame.setFileName(file, format); + // } + + if (openInNewWindow) + { + Desktop.addInternalFrame(newAlignFrame, title, + AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + } + + /* + * Map sequences. At least one should get mapped as we have already passed + * the test for 'mappability'. Any mappings made will be added to the + * protein alignment. + */ + AlignmentUtils.mapProteinToCdna(protein, cdna); + + try + { + newAlignFrame.setMaximum(jalview.bin.Cache.getDefault( + "SHOW_FULLSCREEN", + false)); + } catch (java.beans.PropertyVetoException ex) + { + } + + if (openSplitPane) + { + protein = openSplitFrame(newAlignFrame, thisAlignment, + protein.getCodonFrames()); + } + + /* + * Register the mappings (held on the protein alignment) with the + * StructureSelectionManager (for mouseover linking). + */ + final StructureSelectionManager ssm = StructureSelectionManager + .getStructureSelectionManager(Desktop.instance); + ssm.addMappings(protein.getCodonFrames()); + + return true; } - protected void setShowAutocalculatedAbove(boolean showAutocalculatedAbove) - { - this.showAutocalculatedAbove = showAutocalculatedAbove; + /** + * Helper method to open a new SplitFrame holding linked dna and protein + * alignments. + * + * @param newAlignFrame + * containing a new alignment to be shown + * @param complement + * cdna/protein complement alignment to show in the other split half + * @param mappings + * @return the protein alignment in the split frame + */ + protected AlignmentI openSplitFrame(AlignFrame newAlignFrame, + AlignmentI complement, Set mappings) + { + /* + * Open in split pane. DNA sequence above, protein below. + */ + AlignFrame copyMe = new AlignFrame(complement, + AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); + copyMe.setTitle(getAlignPanel().alignFrame.getTitle()); + + AlignmentI al = newAlignFrame.viewport.getAlignment(); + final AlignFrame proteinFrame = al.isNucleotide() ? copyMe + : newAlignFrame; + final AlignFrame cdnaFrame = al.isNucleotide() ? newAlignFrame + : copyMe; + AlignmentI protein = proteinFrame.viewport.getAlignment(); + protein.setCodonFrames(mappings); + + cdnaFrame.setVisible(true); + proteinFrame.setVisible(true); + String linkedTitle = MessageManager + .getString("label.linked_view_title"); + JInternalFrame splitFrame = new SplitFrame(cdnaFrame, proteinFrame); + Desktop.addInternalFrame(splitFrame, linkedTitle, -1, -1); + + return protein; } public AnnotationColumnChooser getAnnotationColumnSelectionState() @@ -1209,4 +1091,39 @@ public class AlignViewport extends AlignmentViewport implements { this.annotationColumnSelectionState = currentAnnotationColumnSelectionState; } + + @Override + public void setIdWidth(int i) + { + super.setIdWidth(i); + AlignmentPanel ap = getAlignPanel(); + if (ap != null) + { + // modify GUI elements to reflect geometry change + Dimension idw = getAlignPanel().getIdPanel().getIdCanvas() + .getPreferredSize(); + idw.width = i; + getAlignPanel().getIdPanel().getIdCanvas().setPreferredSize(idw); + } + } + + public Rectangle getExplodedGeometry() + { + return explodedGeometry; + } + + public void setExplodedGeometry(Rectangle explodedPosition) + { + this.explodedGeometry = explodedPosition; + } + + public boolean isGatherViewsHere() + { + return gatherViewsHere; + } + + public void setGatherViewsHere(boolean gatherViewsHere) + { + this.gatherViewsHere = gatherViewsHere; + } } diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java index d8b0757..beafa8c 100644 --- a/src/jalview/gui/AlignmentPanel.java +++ b/src/jalview/gui/AlignmentPanel.java @@ -21,6 +21,7 @@ package jalview.gui; import jalview.analysis.AnnotationSorter; +import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; import jalview.bin.Cache; import jalview.datamodel.AlignmentI; @@ -94,9 +95,7 @@ public class AlignmentPanel extends GAlignmentPanel implements * Creates a new AlignmentPanel object. * * @param af - * DOCUMENT ME! * @param av - * DOCUMENT ME! */ public AlignmentPanel(AlignFrame af, final AlignViewport av) { @@ -122,8 +121,6 @@ public class AlignmentPanel extends GAlignmentPanel implements setScrollValues(0, 0); - setAnnotationVisible(av.isShowAnnotation()); - hscroll.addAdjustmentListener(this); vscroll.addAdjustmentListener(this); @@ -141,9 +138,14 @@ public class AlignmentPanel extends GAlignmentPanel implements }); fontChanged(); adjustAnnotationHeight(); - + updateLayout(); } + @Override + public AlignViewportI getAlignViewport() + { + return av; + } public void alignmentChanged() { av.alignmentChanged(this); @@ -163,9 +165,10 @@ public class AlignmentPanel extends GAlignmentPanel implements // to prevent drawing old image FontMetrics fm = getFontMetrics(av.getFont()); - scalePanelHolder.setPreferredSize(new Dimension(10, av.charHeight + scalePanelHolder.setPreferredSize(new Dimension(10, av.getCharHeight() + fm.getDescent())); - idSpaceFillerPanel1.setPreferredSize(new Dimension(10, av.charHeight + idSpaceFillerPanel1.setPreferredSize(new Dimension(10, av + .getCharHeight() + fm.getDescent())); getIdPanel().getIdCanvas().gg = null; @@ -173,6 +176,7 @@ public class AlignmentPanel extends GAlignmentPanel implements getAnnotationPanel().adjustPanelHeight(); Dimension d = calculateIdWidth(); + d.setSize(d.width + 4, d.height); getIdPanel().getIdCanvas().setPreferredSize(d); hscrollFillerPanel.setPreferredSize(d); @@ -181,6 +185,10 @@ public class AlignmentPanel extends GAlignmentPanel implements { overviewPanel.setBoxPosition(); } + if (this.alignFrame.getSplitViewContainer() != null) + { + ((SplitFrame) this.alignFrame.getSplitViewContainer()).adjustLayout(); + } repaint(); } @@ -195,11 +203,21 @@ public class AlignmentPanel extends GAlignmentPanel implements public Dimension calculateIdWidth() { // calculate sensible default width when no preference is available - - int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300); - int maxwidth = Math.max(20, - Math.min(afwidth - 200, 2 * afwidth / 3)); - return calculateIdWidth(maxwidth); + Dimension r = null; + if (av.getIdWidth() < 0) + { + int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300); + int maxwidth = Math.max(20, Math.min(afwidth - 200, 2 * afwidth / 3)); + r = calculateIdWidth(maxwidth); + av.setIdWidth(r.width); + } + else + { + r = new Dimension(); + r.width = av.getIdWidth(); + r.height = 0; + } + return r; } /** @@ -339,7 +357,7 @@ public class AlignmentPanel extends GAlignmentPanel implements } } } - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { if ((startv = av.getStartRes()) >= start) { @@ -412,7 +430,7 @@ public class AlignmentPanel extends GAlignmentPanel implements */ public void setAnnotationVisible(boolean b) { - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { annotationSpaceFillerHolder.setVisible(b); annotationScroller.setVisible(b); @@ -488,13 +506,16 @@ public class AlignmentPanel extends GAlignmentPanel implements } /** - * DOCUMENT ME! + * update alignment layout for viewport settings * * @param wrap * DOCUMENT ME! */ - public void setWrapAlignment(boolean wrap) + public void updateLayout() { + fontChanged(); + setAnnotationVisible(av.isShowAnnotation()); + boolean wrap = av.getWrapAlignment(); av.startSeq = 0; scalePanelHolder.setVisible(!wrap); hscroll.setVisible(!wrap); @@ -605,10 +626,11 @@ public class AlignmentPanel extends GAlignmentPanel implements width = av.getColumnSelection().findColumnPosition(width); } - av.setEndRes((x + (getSeqPanel().seqCanvas.getWidth() / av.charWidth)) - 1); + av.setEndRes((x + (getSeqPanel().seqCanvas.getWidth() / av + .getCharWidth())) - 1); - hextent = getSeqPanel().seqCanvas.getWidth() / av.charWidth; - vextent = getSeqPanel().seqCanvas.getHeight() / av.charHeight; + hextent = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth(); + vextent = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight(); if (hextent > width) { @@ -652,7 +674,6 @@ public class AlignmentPanel extends GAlignmentPanel implements */ public void adjustmentValueChanged(AdjustmentEvent evt) { - int oldX = av.getStartRes(); int oldY = av.getStartSeq(); @@ -859,7 +880,7 @@ public class AlignmentPanel extends GAlignmentPanel implements { int idWidth = getVisibleIdWidth(false); FontMetrics fm = getFontMetrics(av.getFont()); - int scaleHeight = av.charHeight + fm.getDescent(); + int scaleHeight = av.getCharHeight() + fm.getDescent(); pg.setColor(Color.white); pg.fillRect(0, 0, pwidth, pheight); @@ -949,7 +970,7 @@ public class AlignmentPanel extends GAlignmentPanel implements } pg.setColor(currentColor); - pg.fillRect(0, (i - startSeq) * av.charHeight, idWidth, + pg.fillRect(0, (i - startSeq) * av.getCharHeight(), idWidth, av.getCharHeight()); pg.setColor(currentTextColor); @@ -966,7 +987,7 @@ public class AlignmentPanel extends GAlignmentPanel implements pg.drawString( seq.getDisplayId(av.getShowJVSuffix()), xPos, - (((i - startSeq) * av.charHeight) + av.getCharHeight()) + (((i - startSeq) * av.getCharHeight()) + av.getCharHeight()) - (av.getCharHeight() / 5)); } @@ -981,7 +1002,8 @@ public class AlignmentPanel extends GAlignmentPanel implements // draw annotation - need to offset for current scroll position int offset = -getAlabels().getScrollOffset(); pg.translate(0, offset); - pg.translate(-idWidth - 3, (endSeq - startSeq) * av.charHeight + 3); + pg.translate(-idWidth - 3, (endSeq - startSeq) * av.getCharHeight() + + 3); getAlabels().drawComponent(pg, idWidth); pg.translate(idWidth + 3, 0); getAnnotationPanel().renderer.drawComponent(getAnnotationPanel(), av, @@ -1012,7 +1034,6 @@ public class AlignmentPanel extends GAlignmentPanel implements public int printWrappedAlignment(Graphics pg, int pwidth, int pheight, int pi) throws PrinterException { - int annotationHeight = 0; AnnotationLabels labels = null; if (av.isShowAnnotation()) @@ -1021,13 +1042,13 @@ public class AlignmentPanel extends GAlignmentPanel implements labels = new AnnotationLabels(av); } - int hgap = av.charHeight; - if (av.scaleAboveWrapped) + int hgap = av.getCharHeight(); + if (av.getScaleAboveWrapped()) { - hgap += av.charHeight; + hgap += av.getCharHeight(); } - int cHeight = av.getAlignment().getHeight() * av.charHeight + hgap + int cHeight = av.getAlignment().getHeight() * av.getCharHeight() + hgap + annotationHeight; int idWidth = getVisibleIdWidth(false); @@ -1071,18 +1092,19 @@ public class AlignmentPanel extends GAlignmentPanel implements xPos = idWidth - fm.stringWidth(string) - 4; } pg.drawString(string, xPos, - ((i * av.charHeight) + ypos + av.charHeight) - - (av.charHeight / 5)); + ((i * av.getCharHeight()) + ypos + av.getCharHeight()) + - (av.getCharHeight() / 5)); } if (labels != null) { pg.translate(-3, ypos - + (av.getAlignment().getHeight() * av.charHeight)); + + (av.getAlignment().getHeight() * av.getCharHeight())); pg.setFont(av.getFont()); labels.drawComponent(pg, idWidth); pg.translate(+3, -ypos - - (av.getAlignment().getHeight() * av.charHeight)); + - (av.getAlignment().getHeight() * av + .getCharHeight())); } ypos += cHeight; @@ -1149,8 +1171,7 @@ public class AlignmentPanel extends GAlignmentPanel implements if (alignFrame != null && !headless) { alignFrame.setProgressBar(MessageManager.formatMessage( - "status.saving_file", - new String[] + "status.saving_file", new Object[] { type.getLabel() }), progress); } try @@ -1225,9 +1246,9 @@ public class AlignmentPanel extends GAlignmentPanel implements maxwidth = av.getColumnSelection().findColumnPosition(maxwidth); } - int height = ((av.getAlignment().getHeight() + 1) * av.charHeight) + int height = ((av.getAlignment().getHeight() + 1) * av.getCharHeight()) + getScalePanel().getHeight(); - int width = getVisibleIdWidth(false) + (maxwidth * av.charWidth); + int width = getVisibleIdWidth(false) + (maxwidth * av.getCharWidth()); if (av.getWrapAlignment()) { @@ -1283,7 +1304,7 @@ public class AlignmentPanel extends GAlignmentPanel implements // //////////////////////////////////////////// int idWidth = getVisibleIdWidth(false); FontMetrics fm = getFontMetrics(av.getFont()); - int scaleHeight = av.charHeight + fm.getDescent(); + int scaleHeight = av.getCharHeight() + fm.getDescent(); // Gen image map // //////////////////////////////// @@ -1302,33 +1323,32 @@ public class AlignmentPanel extends GAlignmentPanel implements for (s = 0; s < sSize; s++) { - sy = s * av.charHeight + scaleHeight; + sy = s * av.getCharHeight() + scaleHeight; SequenceI seq = av.getAlignment().getSequenceAt(s); - SequenceFeature[] features = seq.getDatasetSequence() - .getSequenceFeatures(); + SequenceFeature[] features = seq.getSequenceFeatures(); SequenceGroup[] groups = av.getAlignment().findAllGroups(seq); for (res = 0; res < alwidth; res++) { text = new StringBuffer(); - Object obj = null; + String triplet = null; if (av.getAlignment().isNucleotide()) { - obj = ResidueProperties.nucleotideName.get(seq.getCharAt(res) + triplet = ResidueProperties.nucleotideName.get(seq + .getCharAt(res) + ""); } else { - obj = ResidueProperties.aa2Triplet.get(seq.getCharAt(res) + triplet = ResidueProperties.aa2Triplet.get(seq.getCharAt(res) + ""); } - if (obj == null) + if (triplet == null) { continue; } - String triplet = obj.toString(); int alIndex = seq.findPosition(res); gSize = groups.length; for (g = 0; g < gSize; g++) @@ -1336,9 +1356,10 @@ public class AlignmentPanel extends GAlignmentPanel implements if (text.length() < 1) { text.append(" 20) { @@ -460,7 +464,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, || (desc.substring(0, 6).toLowerCase().indexOf("") < 0)) { // clean the description ready for embedding in html - desc = new StringBuffer(Pattern.compile("<").matcher(desc) + desc = new StringBuffer(LEFT_ANGLE_BRACKET_PATTERN.matcher(desc) .replaceAll("<")); desc.insert(0, ""); } @@ -621,11 +625,11 @@ public class AnnotationLabels extends JPanel implements MouseListener, item.addActionListener(this); pop.add(item); // JAL-1264 hide all sequence-specific annotations of this type - final String label = aa[selectedRow].label; if (selectedRow < aa.length) { if (aa[selectedRow].sequenceRef != null) { + final String label = aa[selectedRow].label; JMenuItem hideType = new JMenuItem(); String text = MessageManager.getString("label.hide_all") + " " + label; hideType.setText(text); @@ -634,15 +638,18 @@ public class AnnotationLabels extends JPanel implements MouseListener, @Override public void actionPerformed(ActionEvent e) { - for (AlignmentAnnotation ann : ap.av.getAlignment() - .getAlignmentAnnotation()) - { - if (ann.sequenceRef != null && ann.label != null - && ann.label.equals(label)) - { - ann.visible = false; - } - } + AlignmentUtils.showOrHideSequenceAnnotations( + ap.av.getAlignment(), Collections.singleton(label), + null, false, false); + // for (AlignmentAnnotation ann : ap.av.getAlignment() + // .getAlignmentAnnotation()) + // { + // if (ann.sequenceRef != null && ann.label != null + // && ann.label.equals(label)) + // { + // ann.visible = false; + // } + // } refresh(); } }); @@ -665,6 +672,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, // property methods if (selectedRow < aa.length) { + final String label = aa[selectedRow].label; if (!aa[selectedRow].autoCalculated) { if (aa[selectedRow].graph == AlignmentAnnotation.NO_GRAPH) @@ -683,10 +691,10 @@ public class AnnotationLabels extends JPanel implements MouseListener, pop.addSeparator(); // av and sequencegroup need to implement same interface for final JCheckBoxMenuItem cbmi = new JCheckBoxMenuItem( - MessageManager.getString("label.ignore_gaps_consensus"), + MessageManager.getString("label.ignore_gaps_consensus"), (aa[selectedRow].groupRef != null) ? aa[selectedRow].groupRef .getIgnoreGapsConsensus() : ap.av - .getIgnoreGapsConsensus()); + .isIgnoreGapsConsensus()); final AlignmentAnnotation aaa = aa[selectedRow]; cbmi.addActionListener(new ActionListener() { @@ -709,7 +717,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, if (aaa.groupRef != null) { final JCheckBoxMenuItem chist = new JCheckBoxMenuItem( - MessageManager.getString("label.show_group_histogram"), + MessageManager.getString("label.show_group_histogram"), aa[selectedRow].groupRef.isShowConsensusHistogram()); chist.addActionListener(new ActionListener() { @@ -728,7 +736,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, }); pop.add(chist); final JCheckBoxMenuItem cprofl = new JCheckBoxMenuItem( - MessageManager.getString("label.show_group_logo"), + MessageManager.getString("label.show_group_logo"), aa[selectedRow].groupRef.isShowSequenceLogo()); cprofl.addActionListener(new ActionListener() { @@ -747,7 +755,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, }); pop.add(cprofl); final JCheckBoxMenuItem cproflnorm = new JCheckBoxMenuItem( - MessageManager.getString("label.normalise_group_logo"), + MessageManager.getString("label.normalise_group_logo"), aa[selectedRow].groupRef.isNormaliseSequenceLogo()); cproflnorm.addActionListener(new ActionListener() { @@ -772,7 +780,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, else { final JCheckBoxMenuItem chist = new JCheckBoxMenuItem( - MessageManager.getString("label.show_histogram"), av.isShowConsensusHistogram()); + MessageManager.getString("label.show_histogram"), av.isShowConsensusHistogram()); chist.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -791,7 +799,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, }); pop.add(chist); final JCheckBoxMenuItem cprof = new JCheckBoxMenuItem( - MessageManager.getString("label.show_logo"), av.isShowSequenceLogo()); + MessageManager.getString("label.show_logo"), av.isShowSequenceLogo()); cprof.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -810,7 +818,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, }); pop.add(cprof); final JCheckBoxMenuItem cprofnorm = new JCheckBoxMenuItem( - MessageManager.getString("label.normalise_logo"), av.isNormaliseSequenceLogo()); + MessageManager.getString("label.normalise_logo"), av.isNormaliseSequenceLogo()); cprofnorm.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -1122,7 +1130,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, dragEvent.getY() - getScrollOffset()); } - if (!av.wrapAlignment && ((aa == null) || (aa.length < 1))) + if (!av.getWrapAlignment() && ((aa == null) || (aa.length < 1))) { g.drawString(MessageManager.getString("label.right_click"), 2, 8); g.drawString(MessageManager.getString("label.to_add_annotation"), 2, diff --git a/src/jalview/gui/AnnotationPanel.java b/src/jalview/gui/AnnotationPanel.java index e5bed74..c952c13 100755 --- a/src/jalview/gui/AnnotationPanel.java +++ b/src/jalview/gui/AnnotationPanel.java @@ -757,10 +757,10 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, public void drawCursor(Graphics graphics, SequenceI seq, int res, int x1, int y1) { - int pady = av.charHeight / 5; + int pady = av.getCharHeight() / 5; int charOffset = 0; graphics.setColor(Color.black); - graphics.fillRect(x1, y1, av.charWidth, av.charHeight); + graphics.fillRect(x1, y1, av.getCharWidth(), av.getCharHeight()); if (av.validCharWidth) { @@ -768,9 +768,9 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, char s = seq.getCharAt(res); - charOffset = (av.charWidth - fm.charWidth(s)) / 2; + charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2; graphics.drawString(String.valueOf(s), charOffset + x1, - (y1 + av.charHeight) - pady); + (y1 + av.getCharHeight()) - pady); } } @@ -799,7 +799,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, return; } } - imgWidth = (av.endRes - av.startRes + 1) * av.charWidth; + imgWidth = (av.endRes - av.startRes + 1) * av.getCharWidth(); if (imgWidth < 1) { return; @@ -867,7 +867,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, return; } long stime = System.currentTimeMillis(); - gg.copyArea(0, 0, imgWidth, getHeight(), -horizontal * av.charWidth, 0); + gg.copyArea(0, 0, imgWidth, getHeight(), + -horizontal * av.getCharWidth(), 0); long mtime = System.currentTimeMillis(); int sr = av.startRes; int er = av.endRes + 1; @@ -875,7 +876,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, if (horizontal > 0) // scrollbar pulled right, image to the left { - transX = (er - sr - horizontal) * av.charWidth; + transX = (er - sr - horizontal) * av.getCharWidth(); sr = er - horizontal; } else if (horizontal < 0) @@ -960,7 +961,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, } g.setColor(Color.white); - g.fillRect(0, 0, (endRes - startRes) * av.charWidth, getHeight()); + g.fillRect(0, 0, (endRes - startRes) * av.getCharWidth(), getHeight()); g.setFont(av.getFont()); if (fm == null) diff --git a/src/jalview/gui/AppVarnaBinding.java b/src/jalview/gui/AppVarnaBinding.java index 822f81c..7894ee2 100644 --- a/src/jalview/gui/AppVarnaBinding.java +++ b/src/jalview/gui/AppVarnaBinding.java @@ -20,6 +20,7 @@ */ package jalview.gui; +import jalview.structure.AtomSpec; import jalview.util.MessageManager; import java.awt.BorderLayout; @@ -827,8 +828,6 @@ public class AppVarnaBinding extends jalview.ext.varna.JalviewVarnaBinding public void onWarningEmitted(String s) { - // TODO Auto-generated method stub - } public void mouseClicked(MouseEvent e) @@ -852,127 +851,73 @@ public class AppVarnaBinding extends jalview.ext.varna.JalviewVarnaBinding public void mouseEntered(MouseEvent arg0) { - // TODO Auto-generated method stub - } public void mouseExited(MouseEvent arg0) { - // TODO Auto-generated method stub - } public void mousePressed(MouseEvent arg0) { - // TODO Auto-generated method stub - } public void mouseReleased(MouseEvent arg0) { - // TODO Auto-generated method stub - - } - - @Override - public Color getColour(int atomIndex, int pdbResNum, String chain, - String pdbId) - { - // TODO Auto-generated method stub - return null; } @Override public String[] getPdbFile() { - // TODO Auto-generated method stub return null; } @Override - public void highlightAtom(int atomIndex, int pdbResNum, String chain, - String pdbId) - { - // TODO Auto-generated method stub - - } - - @Override - public void mouseOverStructure(int atomIndex, String strInfo) - { - // TODO Auto-generated method stub - - } - - @Override public void releaseReferences(Object svl) { - // TODO Auto-generated method stub - } @Override public void updateColours(Object source) { - // TODO Auto-generated method stub - } @Override public void componentHidden(ComponentEvent e) { - // TODO Auto-generated method stub - } @Override public void componentMoved(ComponentEvent e) { - // TODO Auto-generated method stub - } @Override public void componentResized(ComponentEvent e) { - // TODO Auto-generated method stub - } @Override public void componentShown(ComponentEvent e) { - // TODO Auto-generated method stub - } @Override public void onStructureRedrawn() { - // TODO Auto-generated method stub - } @Override public void onZoomLevelChanged() { - // TODO Auto-generated method stub - } @Override public void onTranslationChanged() { - // TODO Auto-generated method stub + } + @Override + public void highlightAtoms(List atoms) + { } } - -/* - * public static void main(String[] args) { JTextField str = new - * JTextField("ATGC"); - * - * AppVarnaBinding vab = new AppVarnaBinding(); vab.varnagui.set_seq(str); - * vab.varnagui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - * vab.varnagui.pack(); vab.varnagui.setVisible(true); } } - */ diff --git a/src/jalview/gui/CutAndPasteHtmlTransfer.java b/src/jalview/gui/CutAndPasteHtmlTransfer.java index 78d256c..ea5c75e 100644 --- a/src/jalview/gui/CutAndPasteHtmlTransfer.java +++ b/src/jalview/gui/CutAndPasteHtmlTransfer.java @@ -33,6 +33,7 @@ import javax.swing.event.HyperlinkEvent.EventType; import jalview.io.*; import jalview.jbgui.*; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; /** * Cut'n'paste files into the desktop See JAL-1105 @@ -43,7 +44,7 @@ import jalview.util.MessageManager; public class CutAndPasteHtmlTransfer extends GCutAndPasteHtmlTransfer { - AlignViewport viewport; + AlignmentViewport viewport; public CutAndPasteHtmlTransfer() { @@ -102,7 +103,7 @@ public class CutAndPasteHtmlTransfer extends GCutAndPasteHtmlTransfer /** * DOCUMENT ME! */ - public void setForInput(AlignViewport viewport) + public void setForInput(AlignmentViewport viewport) { this.viewport = viewport; if (viewport != null) diff --git a/src/jalview/gui/CutAndPasteTransfer.java b/src/jalview/gui/CutAndPasteTransfer.java index 8b0bafd..22f0a59 100644 --- a/src/jalview/gui/CutAndPasteTransfer.java +++ b/src/jalview/gui/CutAndPasteTransfer.java @@ -20,16 +20,28 @@ */ package jalview.gui; -import java.awt.*; -import java.awt.datatransfer.*; -import java.awt.event.*; -import javax.swing.*; - -import jalview.datamodel.*; -import jalview.io.*; -import jalview.jbgui.*; +import jalview.datamodel.Alignment; +import jalview.io.FormatAdapter; +import jalview.io.IdentifyFile; +import jalview.io.JalviewFileChooser; +import jalview.io.JalviewFileView; +import jalview.jbgui.GCutAndPasteTransfer; import jalview.util.MessageManager; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; + +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; + /** * Cut'n'paste files into the desktop See JAL-1105 * @@ -190,24 +202,19 @@ public class CutAndPasteTransfer extends GCutAndPasteTransfer if (al != null) { + String title = MessageManager.formatMessage( + "label.input_cut_paste_params", new String[] + { format }); if (viewport != null) { - for (int i = 0; i < al.getHeight(); i++) - { - viewport.getAlignment().addSequence(al.getSequenceAt(i)); - } - - viewport.firePropertyChange("alignment", null, viewport - .getAlignment().getSequences()); + viewport.addAlignment(al, title); } else { AlignFrame af = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); af.currentFileFormat = format; - Desktop.addInternalFrame(af, MessageManager.formatMessage( - "label.input_cut_paste_params", new String[] - { format }), AlignFrame.DEFAULT_WIDTH, + Desktop.addInternalFrame(af, title, AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); af.statusBar.setText(MessageManager .getString("label.successfully_pasted_alignment_file")); diff --git a/src/jalview/gui/DasSourceBrowser.java b/src/jalview/gui/DasSourceBrowser.java index 4280db8..fab4cb3 100644 --- a/src/jalview/gui/DasSourceBrowser.java +++ b/src/jalview/gui/DasSourceBrowser.java @@ -20,12 +20,6 @@ */ package jalview.gui; -import jalview.jbgui.GDasSourceBrowser; -import jalview.util.MessageManager; -import jalview.util.TableSorter; -import jalview.ws.dbsources.das.api.DasSourceRegistryI; -import jalview.ws.dbsources.das.api.jalviewSourceI; - import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; @@ -52,6 +46,12 @@ import org.biodas.jdas.schema.sources.COORDINATES; import org.biodas.jdas.schema.sources.PROP; import org.biodas.jdas.schema.sources.VERSION; +import jalview.jbgui.GDasSourceBrowser; +import jalview.util.MessageManager; +import jalview.util.TableSorter; +import jalview.ws.dbsources.das.api.DasSourceRegistryI; +import jalview.ws.dbsources.das.api.jalviewSourceI; + public class DasSourceBrowser extends GDasSourceBrowser implements Runnable, ListSelectionListener { @@ -440,8 +440,7 @@ public class DasSourceBrowser extends GDasSourceBrowser implements seqs.setSelected(seqsrc); JPanel panel = new JPanel(new BorderLayout()); JPanel pane12 = new JPanel(new BorderLayout()); - pane12.add( - new JLabel(MessageManager.getString("label.structure_manager")), + pane12.add(new JLabel(MessageManager.getString("label.name")), BorderLayout.CENTER); pane12.add(nametf, BorderLayout.EAST); panel.add(pane12, BorderLayout.NORTH); diff --git a/src/jalview/gui/FeatureSettings.java b/src/jalview/gui/FeatureSettings.java index 865fbbc..918fc02 100644 --- a/src/jalview/gui/FeatureSettings.java +++ b/src/jalview/gui/FeatureSettings.java @@ -28,6 +28,7 @@ import jalview.io.JalviewFileChooser; import jalview.schemes.AnnotationColourGradient; import jalview.schemes.GraduatedColor; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import jalview.ws.dbsources.das.api.jalviewSourceI; import java.awt.BorderLayout; @@ -428,15 +429,13 @@ public class FeatureSettings extends JPanel String group; for (int i = 0; i < af.getViewport().getAlignment().getHeight(); i++) { - if (af.getViewport().getAlignment().getSequenceAt(i) - .getDatasetSequence().getSequenceFeatures() == null) + tmpfeatures = af.getViewport().getAlignment().getSequenceAt(i) + .getSequenceFeatures(); + if (tmpfeatures == null) { continue; } - tmpfeatures = af.getViewport().getAlignment().getSequenceAt(i) - .getDatasetSequence().getSequenceFeatures(); - int index = 0; while (index < tmpfeatures.length) { @@ -546,7 +545,7 @@ public class FeatureSettings extends JPanel { tmpfeatures = af.getViewport().getAlignment().getSequenceAt(i) - .getDatasetSequence().getSequenceFeatures(); + .getSequenceFeatures(); if (tmpfeatures == null) { continue; @@ -1213,7 +1212,7 @@ public class FeatureSettings extends JPanel { SequenceI[] dataset, seqs; int iSize; - AlignViewport vp = af.getViewport(); + AlignmentViewport vp = af.getViewport(); if (vp.getSelectionGroup() != null && vp.getSelectionGroup().getSize() > 0) { diff --git a/src/jalview/gui/Finder.java b/src/jalview/gui/Finder.java index 5a2271d..3cce82c 100755 --- a/src/jalview/gui/Finder.java +++ b/src/jalview/gui/Finder.java @@ -25,6 +25,7 @@ import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.jbgui.GFinder; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.awt.event.ActionEvent; import java.util.Vector; @@ -52,7 +53,7 @@ public class Finder extends GFinder private static final int WIDTH = 340; - AlignViewport av; + AlignmentViewport av; AlignmentPanel ap; @@ -80,7 +81,7 @@ public class Finder extends GFinder * @param viewport * @param alignPanel */ - public Finder(AlignViewport viewport, AlignmentPanel alignPanel) + public Finder(AlignmentViewport viewport, AlignmentPanel alignPanel) { av = viewport; ap = alignPanel; diff --git a/src/jalview/gui/FontChooser.java b/src/jalview/gui/FontChooser.java index 0f65354..fc66965 100755 --- a/src/jalview/gui/FontChooser.java +++ b/src/jalview/gui/FontChooser.java @@ -20,14 +20,18 @@ */ package jalview.gui; -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -import jalview.bin.*; -import jalview.jbgui.*; +import jalview.bin.Cache; +import jalview.jbgui.GFontChooser; import jalview.util.MessageManager; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.event.ActionEvent; + +import javax.swing.JInternalFrame; +import javax.swing.JLayeredPane; +import javax.swing.JOptionPane; + /** * DOCUMENT ME! * @@ -167,7 +171,7 @@ public class FontChooser extends GFontChooser { if (ap != null) { - ap.av.setFont(oldFont); + ap.av.setFont(oldFont, true); ap.paintAlignment(true); } else if (tp != null) @@ -236,7 +240,7 @@ public class FontChooser extends GFontChooser } else if (ap != null) { - ap.av.setFont(newFont); + ap.av.setFont(newFont, true); ap.fontChanged(); } diff --git a/src/jalview/gui/IdCanvas.java b/src/jalview/gui/IdCanvas.java index 011edf3..a7a4e34 100755 --- a/src/jalview/gui/IdCanvas.java +++ b/src/jalview/gui/IdCanvas.java @@ -20,13 +20,19 @@ */ package jalview.gui; -import java.awt.*; -import java.awt.image.*; +import jalview.datamodel.SequenceI; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; import java.util.List; -import javax.swing.*; - -import jalview.datamodel.*; +import javax.swing.JPanel; /** * DOCUMENT ME! @@ -94,7 +100,7 @@ public class IdCanvas extends JPanel { int xPos = 0; int panelWidth = getWidth(); - int charHeight = av.charHeight; + int charHeight = av.getCharHeight(); if ((searchResults != null) && searchResults.contains(s)) { @@ -128,7 +134,7 @@ public class IdCanvas extends JPanel gg.drawString(s.getDisplayId(av.getShowJVSuffix()), xPos, (((i - starty + 1) * charHeight) + ypos) - (charHeight / 5)); - if (av.hasHiddenRows() && av.showHiddenMarkers) + if (av.hasHiddenRows() && av.getShowHiddenMarkers()) { drawMarker(i, starty, ypos); } @@ -150,7 +156,8 @@ public class IdCanvas extends JPanel return; } - gg.copyArea(0, 0, getWidth(), imgHeight, 0, -vertical * av.charHeight); + gg.copyArea(0, 0, getWidth(), imgHeight, 0, + -vertical * av.getCharHeight()); int ss = av.startSeq; int es = av.endSeq; @@ -166,7 +173,7 @@ public class IdCanvas extends JPanel } else { - transY = imgHeight - (vertical * av.charHeight); + transY = imgHeight - (vertical * av.getCharHeight()); } } else if (vertical < 0) @@ -211,7 +218,7 @@ public class IdCanvas extends JPanel int oldHeight = imgHeight; imgHeight = getHeight(); - imgHeight -= (imgHeight % av.charHeight); + imgHeight -= (imgHeight % av.getCharHeight()); if (imgHeight < 1) { @@ -245,7 +252,7 @@ public class IdCanvas extends JPanel */ void drawIds(int starty, int endy) { - if (av.seqNameItalics) + if (av.isSeqNameItalics()) { setIdfont(new Font(av.getFont().getName(), Font.ITALIC, av.getFont() .getSize())); @@ -293,13 +300,13 @@ public class IdCanvas extends JPanel } } - int hgap = av.charHeight; - if (av.scaleAboveWrapped) + int hgap = av.getCharHeight(); + if (av.getScaleAboveWrapped()) { - hgap += av.charHeight; + hgap += av.getCharHeight(); } - int cHeight = alheight * av.charHeight + hgap + annotationHeight; + int cHeight = alheight * av.getCharHeight() + hgap + annotationHeight; int rowSize = av.getEndRes() - av.getStartRes(); @@ -324,9 +331,9 @@ public class IdCanvas extends JPanel if (labels != null && av.isShowAnnotation()) { - gg.translate(0, ypos + (alheight * av.charHeight)); + gg.translate(0, ypos + (alheight * av.getCharHeight())); labels.drawComponent(gg, getWidth()); - gg.translate(0, -ypos - (alheight * av.charHeight)); + gg.translate(0, -ypos - (alheight * av.getCharHeight())); } } } @@ -376,8 +383,8 @@ public class IdCanvas extends JPanel gg.setColor(currentColor); - gg.fillRect(0, (i - starty) * av.charHeight, getWidth(), - av.charHeight); + gg.fillRect(0, (i - starty) * av.getCharHeight(), getWidth(), + av.getCharHeight()); gg.setColor(currentTextColor); @@ -389,10 +396,10 @@ public class IdCanvas extends JPanel } gg.drawString(string, xPos, - (((i - starty) * av.charHeight) + av.charHeight) - - (av.charHeight / 5)); + (((i - starty) * av.getCharHeight()) + av.getCharHeight()) + - (av.getCharHeight() / 5)); - if (av.hasHiddenRows() && av.showHiddenMarkers) + if (av.hasHiddenRows() && av.getShowHiddenMarkers()) { drawMarker(i, starty, 0); } @@ -441,24 +448,27 @@ public class IdCanvas extends JPanel { gg.fillPolygon( new int[] - { getWidth() - av.charHeight, getWidth() - av.charHeight, + { getWidth() - av.getCharHeight(), + getWidth() - av.getCharHeight(), getWidth() }, new int[] { - (i - starty) * av.charHeight + yoffset, - (i - starty) * av.charHeight + yoffset + av.charHeight - / 4, (i - starty) * av.charHeight + yoffset }, 3); + (i - starty) * av.getCharHeight() + yoffset, + (i - starty) * av.getCharHeight() + yoffset + + av.getCharHeight() / 4, + (i - starty) * av.getCharHeight() + yoffset }, 3); } if (above) { gg.fillPolygon( new int[] - { getWidth() - av.charHeight, getWidth() - av.charHeight, + { getWidth() - av.getCharHeight(), + getWidth() - av.getCharHeight(), getWidth() }, new int[] { - (i - starty + 1) * av.charHeight + yoffset, - (i - starty + 1) * av.charHeight + yoffset - - av.charHeight / 4, - (i - starty + 1) * av.charHeight + yoffset }, 3); + (i - starty + 1) * av.getCharHeight() + yoffset, + (i - starty + 1) * av.getCharHeight() + yoffset + - av.getCharHeight() / 4, + (i - starty + 1) * av.getCharHeight() + yoffset }, 3); } } diff --git a/src/jalview/gui/IdPanel.java b/src/jalview/gui/IdPanel.java index 6aad6c5..4ea35ca 100755 --- a/src/jalview/gui/IdPanel.java +++ b/src/jalview/gui/IdPanel.java @@ -110,7 +110,7 @@ public class IdPanel extends JPanel implements MouseListener, StringBuffer tip = new StringBuffer(64); seqAnnotReport .createSequenceAnnotationReport(tip, sequence, - av.isShowDbRefs(), av.isShowNpFeats(), + av.isShowDBRefs(), av.isShowNPFeats(), sp.seqCanvas.fr.getMinMax()); setToolTipText("" + sequence.getDisplayId(true) + " " + tip.toString() + ""); @@ -323,8 +323,7 @@ public class IdPanel extends JPanel implements MouseListener, // build a new links menu based on the current links + any non-positional // features Vector nlinks = new Vector(Preferences.sequenceURLLinks); - SequenceFeature sf[] = sq == null ? null : sq.getDatasetSequence() - .getSequenceFeatures(); + SequenceFeature sf[] = sq == null ? null : sq.getSequenceFeatures(); for (int sl = 0; sf != null && sl < sf.length; sl++) { if (sf[sl].begin == sf[sl].end && sf[sl].begin == 0) @@ -363,6 +362,9 @@ public class IdPanel extends JPanel implements MouseListener, { selectSeq(seq); } + // TODO is this addition ok here? + av.isSelectionGroupChanged(true); + alignPanel.paintAlignment(true); } diff --git a/src/jalview/gui/IdwidthAdjuster.java b/src/jalview/gui/IdwidthAdjuster.java index e3252d6..71e2040 100755 --- a/src/jalview/gui/IdwidthAdjuster.java +++ b/src/jalview/gui/IdwidthAdjuster.java @@ -20,9 +20,14 @@ */ package jalview.gui; -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; + +import javax.swing.JPanel; /** * DOCUMENT ME! @@ -119,13 +124,13 @@ public class IdwidthAdjuster extends JPanel implements MouseListener, { active = true; - Dimension d = ap.getIdPanel().getIdCanvas().getPreferredSize(); + int curwidth = ap.getAlignViewport().getIdWidth(); int dif = evt.getX() - oldX; - if (((d.width + dif) > 20) || (dif > 0)) + if (((curwidth + dif) > 20) || (dif > 0)) { - ap.getIdPanel().getIdCanvas().setPreferredSize(new Dimension(d.width + dif, - d.height)); + ap.getAlignViewport().setIdWidth(curwidth + dif); + ap.paintAlignment(true); } diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java index fb53900..8beb26f 100644 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -20,8 +20,47 @@ */ package jalview.gui; +import java.awt.Rectangle; +import java.io.BufferedReader; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.lang.reflect.InvocationTargetException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.Vector; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; +import java.util.jar.JarOutputStream; + +import javax.swing.JInternalFrame; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; + +import org.exolab.castor.xml.Unmarshaller; + import jalview.api.structures.JalviewStructureDisplayI; import jalview.bin.Cache; +import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; @@ -30,7 +69,6 @@ import jalview.datamodel.SequenceI; import jalview.datamodel.StructureViewerModel; import jalview.datamodel.StructureViewerModel.StructureData; import jalview.schemabinding.version2.AlcodMap; -import jalview.schemabinding.version2.Alcodon; import jalview.schemabinding.version2.AlcodonFrame; import jalview.schemabinding.version2.Annotation; import jalview.schemabinding.version2.AnnotationColours; @@ -83,44 +121,6 @@ import jalview.ws.params.ArgumentI; import jalview.ws.params.AutoCalcSetting; import jalview.ws.params.WsParamSetI; -import java.awt.Rectangle; -import java.io.BufferedReader; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.lang.reflect.InvocationTargetException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.StringTokenizer; -import java.util.Vector; -import java.util.jar.JarEntry; -import java.util.jar.JarInputStream; -import java.util.jar.JarOutputStream; - -import javax.swing.JInternalFrame; -import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; - -import org.exolab.castor.xml.Unmarshaller; - /** * Write out the current jalview desktop state as a Jalview XML stream. * @@ -150,6 +150,12 @@ public class Jalview2XML boolean raiseGUI = true; // whether errors are raised in dialog boxes or not + /* + * Map of reconstructed AlignFrame objects that appear to have come from + * SplitFrame objects (have a dna/protein complement view). + */ + private Map splitFrameCandidates = new HashMap(); + /** * create/return unique hash string for sq * @@ -298,12 +304,12 @@ public class Jalview2XML } /** - * This maintains a list of viewports, the key being the seqSetId. Important - * to set historyItem and redoList for multiple views + * This maintains a map of viewports, the key being the seqSetId. Important to + * set historyItem and redoList for multiple views */ - Hashtable viewportsAdded; + Map viewportsAdded = new HashMap(); - Hashtable annotationIds = new Hashtable(); + Map annotationIds = new HashMap(); String uniqueSetSuffix = ""; @@ -359,7 +365,7 @@ public class Jalview2XML */ public void saveState(JarOutputStream jout) { - JInternalFrame[] frames = Desktop.desktop.getAllFrames(); + AlignFrame[] frames = Desktop.getAlignFrames(); // Desktop.desktop.getAllFrames(); if (frames == null) { @@ -379,67 +385,61 @@ public class Jalview2XML // REVERSE ORDER for (int i = frames.length - 1; i > -1; i--) { - if (frames[i] instanceof AlignFrame) + AlignFrame af = frames[i]; + // skip ? + if (skipList != null + && skipList + .containsKey(af.getViewport().getSequenceSetId())) { - AlignFrame af = (AlignFrame) frames[i]; - // skip ? - if (skipList != null - && skipList.containsKey(af.getViewport() - .getSequenceSetId())) - { - continue; - } + continue; + } + + String shortName = af.getTitle(); + + if (shortName.indexOf(File.separatorChar) > -1) + { + shortName = shortName.substring(shortName + .lastIndexOf(File.separatorChar) + 1); + } - String shortName = af.getTitle(); + int count = 1; - if (shortName.indexOf(File.separatorChar) > -1) + while (shortNames.contains(shortName)) + { + if (shortName.endsWith("_" + (count - 1))) { - shortName = shortName.substring(shortName - .lastIndexOf(File.separatorChar) + 1); + shortName = shortName.substring(0, shortName.lastIndexOf("_")); } - int count = 1; + shortName = shortName.concat("_" + count); + count++; + } - while (shortNames.contains(shortName)) - { - if (shortName.endsWith("_" + (count - 1))) - { - shortName = shortName - .substring(0, shortName.lastIndexOf("_")); - } + shortNames.addElement(shortName); - shortName = shortName.concat("_" + count); - count++; - } + if (!shortName.endsWith(".xml")) + { + shortName = shortName + ".xml"; + } - shortNames.addElement(shortName); + int ap, apSize = af.alignPanels.size(); - if (!shortName.endsWith(".xml")) + for (ap = 0; ap < apSize; ap++) + { + AlignmentPanel apanel = af.alignPanels.get(ap); + String fileName = apSize == 1 ? shortName : ap + shortName; + if (!fileName.endsWith(".xml")) { - shortName = shortName + ".xml"; + fileName = fileName + ".xml"; } - int ap, apSize = af.alignPanels.size(); + saveState(apanel, fileName, jout); - for (ap = 0; ap < apSize; ap++) + String dssid = getDatasetIdRef(af.getViewport().getAlignment() + .getDataset()); + if (!dsses.containsKey(dssid)) { - AlignmentPanel apanel = (AlignmentPanel) af.alignPanels - .elementAt(ap); - String fileName = apSize == 1 ? shortName : ap + shortName; - if (!fileName.endsWith(".xml")) - { - fileName = fileName + ".xml"; - } - - saveState(apanel, fileName, jout); - - String dssid = getDatasetIdRef(af.getViewport().getAlignment() - .getDataset()); - if (!dsses.containsKey(dssid)) - { - dsses.put(dssid, af); - } - + dsses.put(dssid, af); } } } @@ -473,15 +473,15 @@ public class Jalview2XML { try { - int ap, apSize = af.alignPanels.size(); + int ap = 0; + int apSize = af.alignPanels.size(); FileOutputStream fos = new FileOutputStream(jarFile); JarOutputStream jout = new JarOutputStream(fos); Hashtable dsses = new Hashtable(); - for (ap = 0; ap < apSize; ap++) + for (AlignmentPanel apanel : af.alignPanels) { - AlignmentPanel apanel = (AlignmentPanel) af.alignPanels - .elementAt(ap); String jfileName = apSize == 1 ? fileName : fileName + ap; + ap++; if (!jfileName.endsWith(".xml")) { jfileName = jfileName + ".xml"; @@ -682,9 +682,9 @@ public class Jalview2XML } } - if (jdatasq.getSequenceFeatures() != null) + if (jds.getSequenceFeatures() != null) { - jalview.datamodel.SequenceFeature[] sf = jdatasq + jalview.datamodel.SequenceFeature[] sf = jds .getSequenceFeatures(); int index = 0; while (index < sf.length) @@ -780,8 +780,7 @@ public class Jalview2XML { byte[] data = new byte[(int) file.length()]; jout.putNextEntry(new JarEntry(entry.getId())); - dis = new DataInputStream( - new FileInputStream(file)); + dis = new DataInputStream(new FileInputStream(file)); dis.readFully(data); DataOutputStream dout = new DataOutputStream(jout); @@ -837,31 +836,18 @@ public class Jalview2XML jal = av.getAlignment(); } // SAVE MAPPINGS - if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0) + if (jal.getCodonFrames() != null) { - jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames(); - for (int i = 0; i < jac.length; i++) + Set jac = jal.getCodonFrames(); + for (AlignedCodonFrame acf : jac) { AlcodonFrame alc = new AlcodonFrame(); vamsasSet.addAlcodonFrame(alc); - for (int p = 0; p < jac[i].aaWidth; p++) + if (acf.getProtMappings() != null + && acf.getProtMappings().length > 0) { - Alcodon cmap = new Alcodon(); - if (jac[i].codons[p] != null) - { - // Null codons indicate a gapped column in the translated peptide - // alignment. - cmap.setPos1(jac[i].codons[p][0]); - cmap.setPos2(jac[i].codons[p][1]); - cmap.setPos3(jac[i].codons[p][2]); - } - alc.addAlcodon(cmap); - } - if (jac[i].getProtMappings() != null - && jac[i].getProtMappings().length > 0) - { - SequenceI[] dnas = jac[i].getdnaSeqs(); - jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings(); + SequenceI[] dnas = acf.getdnaSeqs(); + jalview.datamodel.Mapping[] pmaps = acf.getProtMappings(); for (int m = 0; m < pmaps.length; m++) { AlcodMap alcmap = new AlcodMap(); @@ -871,6 +857,37 @@ public class Jalview2XML alc.addAlcodMap(alcmap); } } + +// { +// AlcodonFrame alc = new AlcodonFrame(); +// vamsasSet.addAlcodonFrame(alc); +// for (int p = 0; p < acf.aaWidth; p++) +// { +// Alcodon cmap = new Alcodon(); +// if (acf.codons[p] != null) +// { +// // Null codons indicate a gapped column in the translated peptide +// // alignment. +// cmap.setPos1(acf.codons[p][0]); +// cmap.setPos2(acf.codons[p][1]); +// cmap.setPos3(acf.codons[p][2]); +// } +// alc.addAlcodon(cmap); +// } +// if (acf.getProtMappings() != null +// && acf.getProtMappings().length > 0) +// { +// SequenceI[] dnas = acf.getdnaSeqs(); +// jalview.datamodel.Mapping[] pmaps = acf.getProtMappings(); +// for (int m = 0; m < pmaps.length; m++) +// { +// AlcodMap alcmap = new AlcodMap(); +// alcmap.setDnasq(seqHash(dnas[m])); +// alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null, +// false)); +// alc.addAlcodMap(alcmap); +// } +// } } } @@ -1031,23 +1048,22 @@ public class Jalview2XML view.setSequenceSetId(makeHashCode(av.getSequenceSetId(), av.getSequenceSetId())); view.setId(av.getViewId()); - view.setViewName(av.viewName); - view.setGatheredViews(av.gatherViewsHere); - - if (ap.av.explodedPosition != null) + if (av.getCodingComplement() != null) { - view.setXpos(av.explodedPosition.x); - view.setYpos(av.explodedPosition.y); - view.setWidth(av.explodedPosition.width); - view.setHeight(av.explodedPosition.height); + view.setComplementId(av.getCodingComplement().getViewId()); } - else + view.setViewName(av.viewName); + view.setGatheredViews(av.isGatherViewsHere()); + + Rectangle position = ap.av.getExplodedGeometry(); + if (position == null) { - view.setXpos(ap.alignFrame.getBounds().x); - view.setYpos(ap.alignFrame.getBounds().y); - view.setWidth(ap.alignFrame.getBounds().width); - view.setHeight(ap.alignFrame.getBounds().height); + position = ap.alignFrame.getBounds(); } + view.setXpos(position.x); + view.setYpos(position.y); + view.setWidth(position.width); + view.setHeight(position.height); view.setStartRes(av.startRes); view.setStartSeq(av.startSeq); @@ -1097,7 +1113,7 @@ public class Jalview2XML view.setFontName(av.font.getName()); view.setFontSize(av.font.getSize()); view.setFontStyle(av.font.getStyle()); - view.setRenderGaps(av.renderGaps); + view.setRenderGaps(av.isRenderGaps()); view.setShowAnnotation(av.isShowAnnotation()); view.setShowBoxes(av.getShowBoxes()); view.setShowColourText(av.getColourText()); @@ -1107,25 +1123,26 @@ public class Jalview2XML view.setShowText(av.getShowText()); view.setShowUnconserved(av.getShowUnconserved()); view.setWrapAlignment(av.getWrapAlignment()); - view.setTextCol1(av.textColour.getRGB()); - view.setTextCol2(av.textColour2.getRGB()); - view.setTextColThreshold(av.thresholdTextColour); + view.setTextCol1(av.getTextColour().getRGB()); + view.setTextCol2(av.getTextColour2().getRGB()); + view.setTextColThreshold(av.getThresholdTextColour()); view.setShowConsensusHistogram(av.isShowConsensusHistogram()); view.setShowSequenceLogo(av.isShowSequenceLogo()); view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo()); view.setShowGroupConsensus(av.isShowGroupConsensus()); view.setShowGroupConservation(av.isShowGroupConservation()); - view.setShowNPfeatureTooltip(av.isShowNpFeats()); - view.setShowDbRefTooltip(av.isShowDbRefs()); + view.setShowNPfeatureTooltip(av.isShowNPFeats()); + view.setShowDbRefTooltip(av.isShowDBRefs()); view.setFollowHighlight(av.followHighlight); view.setFollowSelection(av.followSelection); - view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus()); + view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus()); if (av.getFeaturesDisplayed() != null) { jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings(); - String[] renderOrder = ap.getSeqPanel().seqCanvas.getFeatureRenderer() - .getRenderOrder().toArray(new String[0]); + String[] renderOrder = ap.getSeqPanel().seqCanvas + .getFeatureRenderer().getRenderOrder() + .toArray(new String[0]); Vector settingsAdded = new Vector(); Object gstyle = null; @@ -1152,7 +1169,8 @@ public class Jalview2XML } else { - setting.setColour(ap.getSeqPanel().seqCanvas.getFeatureRenderer() + setting.setColour(ap.getSeqPanel().seqCanvas + .getFeatureRenderer() .getColour(renderOrder[ro]).getRGB()); } @@ -1196,8 +1214,8 @@ public class Jalview2XML settingsAdded.addElement(key); } // is groups actually supposed to be a map here ? - en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().getFeatureGroups() - .iterator(); + en = ap.getSeqPanel().seqCanvas.getFeatureRenderer() + .getFeatureGroups().iterator(); Vector groupsAdded = new Vector(); while (en.hasNext()) { @@ -1230,8 +1248,8 @@ public class Jalview2XML for (int c = 0; c < av.getColumnSelection().getHiddenColumns() .size(); c++) { - int[] region = av.getColumnSelection() - .getHiddenColumns().get(c); + int[] region = av.getColumnSelection().getHiddenColumns() + .get(c); HiddenColumns hc = new HiddenColumns(); hc.setStart(region[0]); hc.setEnd(region[1]); @@ -1302,17 +1320,14 @@ public class Jalview2XML Pdbids pdb, PDBEntry entry, List viewIds, String matchedFile, StructureViewerBase viewFrame) { - final AAStructureBindingModel bindingModel = viewFrame - .getBinding(); - for (int peid = 0; peid < bindingModel - .getPdbCount(); peid++) + final AAStructureBindingModel bindingModel = viewFrame.getBinding(); + for (int peid = 0; peid < bindingModel.getPdbCount(); peid++) { final PDBEntry pdbentry = bindingModel.getPdbEntry(peid); final String pdbId = pdbentry.getId(); if (!pdbId.equals(entry.getId()) && !(entry.getId().length() > 4 && entry.getId() - .toLowerCase() - .startsWith(pdbId.toLowerCase()))) + .toLowerCase().startsWith(pdbId.toLowerCase()))) { continue; } @@ -1320,8 +1335,7 @@ public class Jalview2XML { matchedFile = pdbentry.getFile(); } - else if (!matchedFile.equals(pdbentry - .getFile())) + else if (!matchedFile.equals(pdbentry.getFile())) { Cache.log .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): " @@ -1334,8 +1348,7 @@ public class Jalview2XML // 1QIP==1qipA) String statestring = viewFrame.getStateInfo(); - for (int smap = 0; smap < viewFrame.getBinding() - .getSequence()[peid].length; smap++) + for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++) { // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1) if (jds == viewFrame.getBinding().getSequence()[peid][smap]) @@ -1349,8 +1362,7 @@ public class Jalview2XML final String viewId = viewFrame.getViewId(); state.setViewId(viewId); state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap)); - state.setColourwithAlignPanel(viewFrame - .isUsedforcolourby(ap)); + state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap)); state.setColourByJmol(viewFrame.isColouredByViewer()); /* * Only store each structure viewer's state once in each XML document. @@ -1645,7 +1657,9 @@ public class Jalview2XML return false; } } - throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()})); + throw new Error(MessageManager.formatMessage( + "error.unsupported_version_calcIdparam", new Object[] + { calcIdParam.toString() })); } /** @@ -1767,20 +1781,20 @@ public class Jalview2XML mp = new Mapping(); jalview.util.MapList mlst = jmp.getMap(); - int r[] = mlst.getFromRanges(); - for (int s = 0; s < r.length; s += 2) + List r = mlst.getFromRanges(); + for (int[] range : r) { MapListFrom mfrom = new MapListFrom(); - mfrom.setStart(r[s]); - mfrom.setEnd(r[s + 1]); + mfrom.setStart(range[0]); + mfrom.setEnd(range[1]); mp.addMapListFrom(mfrom); } r = mlst.getToRanges(); - for (int s = 0; s < r.length; s += 2) + for (int[] range : r) { MapListTo mto = new MapListTo(); - mto.setStart(r[s]); - mto.setEnd(r[s + 1]); + mto.setStart(range[0]); + mto.setEnd(range[1]); mp.addMapListTo(mto); } mp.setMapFromUnit(mlst.getFromRatio()); @@ -1977,7 +1991,7 @@ public class Jalview2XML errorMessage = null; uniqueSetSuffix = null; seqRefIds = null; - viewportsAdded = null; + viewportsAdded.clear(); frefedSequence = null; if (file.startsWith("http://")) @@ -2029,17 +2043,13 @@ public class Jalview2XML { seqRefIds = new HashMap(); } - if (viewportsAdded == null) - { - viewportsAdded = new Hashtable(); - } if (frefedSequence == null) { frefedSequence = new Vector(); } - jalview.gui.AlignFrame af = null, _af = null; - Hashtable gatherToThisFrame = new Hashtable(); + AlignFrame af = null, _af = null; + Map gatherToThisFrame = new HashMap(); final String file = jprovider.getFilename(); try { @@ -2069,7 +2079,7 @@ public class Jalview2XML if (object.getJalviewModelSequence().getViewportCount() > 0) { af = _af; - if (af.viewport.gatherViewsHere) + if (af.viewport.isGatherViewsHere()) { gatherToThisFrame.put(af.viewport.getSequenceSetId(), af); } @@ -2139,11 +2149,20 @@ public class Jalview2XML Desktop.instance.stopLoading(); } - Enumeration en = gatherToThisFrame.elements(); - while (en.hasMoreElements()) + /* + * Regather multiple views (with the same sequence set id) to the frame (if + * any) that is flagged as the one to gather to, i.e. convert them to tabbed + * views instead of separate frames. Note this doesn't restore a state where + * some expanded views in turn have tabbed views - the last "first tab" read + * in will play the role of gatherer for all. + */ + for (AlignFrame fr : gatherToThisFrame.values()) { - Desktop.instance.gatherViews((AlignFrame) en.nextElement()); + Desktop.instance.gatherViews(fr); } + + restoreSplitFrames(); + if (errorMessage != null) { reportErrors(); @@ -2152,6 +2171,102 @@ public class Jalview2XML } /** + * Try to reconstruct and display SplitFrame windows, where each contains + * complementary dna and protein alignments. Done by pairing up AlignFrame + * objects (created earlier) which have complementary viewport ids associated. + */ + protected void restoreSplitFrames() + { + List gatherTo = new ArrayList(); + List addedToSplitFrames = new ArrayList(); + Map dna = new HashMap(); + + /* + * Identify the DNA alignments + */ + for (Entry candidate : splitFrameCandidates + .entrySet()) + { + AlignFrame af = candidate.getValue(); + if (af.getViewport().getAlignment().isNucleotide()) + { + dna.put(candidate.getKey().getId(), af); + } + } + + /* + * Try to match up the protein complements + */ + for (Entry candidate : splitFrameCandidates + .entrySet()) + { + AlignFrame af = candidate.getValue(); + if (!af.getViewport().getAlignment().isNucleotide()) + { + String complementId = candidate.getKey().getComplementId(); + // only non-null complements should be in the Map + if (complementId != null && dna.containsKey(complementId)) + { + final AlignFrame dnaFrame = dna.get(complementId); + SplitFrame sf = createSplitFrame(dnaFrame, af); + addedToSplitFrames.add(dnaFrame); + addedToSplitFrames.add(af); + if (af.viewport.isGatherViewsHere()) + { + gatherTo.add(sf); + } + } + } + } + + /* + * Open any that we failed to pair up (which shouldn't happen!) as + * standalone AlignFrame's. + */ + for (Entry candidate : splitFrameCandidates + .entrySet()) + { + AlignFrame af = candidate.getValue(); + if (!addedToSplitFrames.contains(af)) { + Viewport view = candidate.getKey(); + Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(), + view.getHeight()); + System.err.println("Failed to restore view " + view.getTitle() + + " to split frame"); + } + } + + /* + * Gather back into tabbed views as flagged. + */ + for (SplitFrame sf : gatherTo) + { + Desktop.instance.gatherViews(sf); + } + + splitFrameCandidates.clear(); + } + + /** + * Construct and display one SplitFrame holding DNA and protein alignments. + * + * @param dnaFrame + * @param proteinFrame + * @return + */ + protected SplitFrame createSplitFrame(AlignFrame dnaFrame, + AlignFrame proteinFrame) + { + SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame); + String title = MessageManager.getString("label.linked_view_title"); + int width = (int) dnaFrame.getBounds().getWidth(); + int height = (int) (dnaFrame.getBounds().getHeight() + + proteinFrame.getBounds().getHeight() + 50); + Desktop.addInternalFrame(splitFrame, title, width, height); + return splitFrame; + } + + /** * check errorMessage for a valid error message and raise an error box in the * GUI or write the current errorMessage to stderr and then clear the error * state. @@ -2188,7 +2303,7 @@ public class Jalview2XML errorMessage = null; } - Hashtable alreadyLoadedPDB; + Map alreadyLoadedPDB = new HashMap(); /** * when set, local views will be updated from view stored in JalviewXML @@ -2199,11 +2314,6 @@ public class Jalview2XML String loadPDBFile(jarInputStreamProvider jprovider, String pdbId) { - if (alreadyLoadedPDB == null) - { - alreadyLoadedPDB = new Hashtable(); - } - if (alreadyLoadedPDB.containsKey(pdbId)) { return alreadyLoadedPDB.get(pdbId).toString(); @@ -2305,10 +2415,10 @@ public class Jalview2XML // //////////////////////////////// // LOAD SEQUENCES - Vector hiddenSeqs = null; + List hiddenSeqs = null; jalview.datamodel.Sequence jseq; - ArrayList tmpseqs = new ArrayList(); + List tmpseqs = new ArrayList(); boolean multipleView = false; @@ -2340,10 +2450,10 @@ public class Jalview2XML { if (hiddenSeqs == null) { - hiddenSeqs = new Vector(); + hiddenSeqs = new ArrayList(); } - hiddenSeqs.addElement(seqRefIds.get(seqId)); + hiddenSeqs.add(seqRefIds.get(seqId)); } } @@ -2351,13 +2461,10 @@ public class Jalview2XML // / // Create the alignment object from the sequence set // /////////////////////////////// - jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs - .size()]; - - tmpseqs.toArray(orderedSeqs); + SequenceI[] orderedSeqs = tmpseqs + .toArray(new SequenceI[tmpseqs.size()]); - jalview.datamodel.Alignment al = new jalview.datamodel.Alignment( - orderedSeqs); + Alignment al = new Alignment(orderedSeqs); // / Add the alignment properties for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++) @@ -2384,7 +2491,7 @@ public class Jalview2XML } // /////////////////////////////// - Hashtable pdbloaded = new Hashtable(); + Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this?? if (!multipleView) { // load sequence features, database references and any associated PDB @@ -2443,8 +2550,7 @@ public class Jalview2XML } } StructureSelectionManager.getStructureSelectionManager( - Desktop.instance) - .registerPDBEntry(entry); + Desktop.instance).registerPDBEntry(entry); al.getSequenceAt(i).getDatasetSequence().addPDBId(entry); } } @@ -2461,35 +2567,13 @@ public class Jalview2XML AlcodonFrame[] alc = vamsasSet.getAlcodonFrame(); for (int i = 0; i < alc.length; i++) { - jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame( - alc[i].getAlcodonCount()); - if (alc[i].getAlcodonCount() > 0) - { - Alcodon[] alcods = alc[i].getAlcodon(); - for (int p = 0; p < cf.codons.length; p++) - { - if (alcods[p].hasPos1() && alcods[p].hasPos2() - && alcods[p].hasPos3()) - { - // translated codons require three valid positions - cf.codons[p] = new int[3]; - cf.codons[p][0] = (int) alcods[p].getPos1(); - cf.codons[p][1] = (int) alcods[p].getPos2(); - cf.codons[p][2] = (int) alcods[p].getPos3(); - } - else - { - cf.codons[p] = null; - } - } - } + AlignedCodonFrame cf = new AlignedCodonFrame(); if (alc[i].getAlcodMapCount() > 0) { AlcodMap[] maps = alc[i].getAlcodMap(); for (int m = 0; m < maps.length; m++) { - SequenceI dnaseq = seqRefIds - .get(maps[m].getDnasq()); + SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq()); // Load Mapping jalview.datamodel.Mapping mapping = null; // attach to dna sequence reference. @@ -2511,12 +2595,11 @@ public class Jalview2XML } al.addCodonFrame(cf); } - } // //////////////////////////////// // LOAD ANNOTATIONS - ArrayList autoAlan = new ArrayList(); + List autoAlan = new ArrayList(); /** * store any annotations which forward reference a group's ID */ @@ -2555,8 +2638,7 @@ public class Jalview2XML if (an[i].getId() != null && annotationIds.containsKey(an[i].getId())) { - jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds - .get(an[i].getId()); + AlignmentAnnotation jda = annotationIds.get(an[i].getId()); // in principle Visible should always be true for annotation displayed // in multiple views if (an[i].hasVisible()) @@ -2766,8 +2848,7 @@ public class Jalview2XML for (int s = 0; s < groups[i].getSeqCount(); s++) { String seqId = groups[i].getSeq(s) + ""; - jalview.datamodel.SequenceI ts = seqRefIds - .get(seqId); + jalview.datamodel.SequenceI ts = seqRefIds.get(seqId); if (ts != null) { @@ -3057,10 +3138,10 @@ public class Jalview2XML for (int s = 0; s < structureStateCount; s++) { // check to see if we haven't already created this structure view - final StructureState structureState = ids[p].getStructureState(s); + final StructureState structureState = ids[p] + .getStructureState(s); String sviewid = (structureState.getViewId() == null) ? null - : structureState.getViewId() - + uniqueSetSuffix; + : structureState.getViewId() + uniqueSetSuffix; jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry(); // Originally : ids[p].getFile() // : TODO: verify external PDB file recovery still works in normal @@ -3077,8 +3158,8 @@ public class Jalview2XML // Desktop.desktop.getComponentAt(x, y); // TODO: NOW: check that this recovers the PDB file correctly. String pdbFile = loadPDBFile(jprovider, ids[p].getId()); - jalview.datamodel.SequenceI seq = seqRefIds - .get(jseqs[i].getId() + ""); + jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i] + .getId() + ""); if (sviewid == null) { sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width @@ -3086,8 +3167,8 @@ public class Jalview2XML } if (!structureViewers.containsKey(sviewid)) { - structureViewers.put(sviewid, new StructureViewerModel(x, y, width, height, - false, false, true)); + structureViewers.put(sviewid, new StructureViewerModel(x, y, + width, height, false, false, true)); // Legacy pre-2.7 conversion JAL-823 : // do not assume any view has to be linked for colour by // sequence @@ -3117,8 +3198,7 @@ public class Jalview2XML * pre-2.7 projects) */ boolean colourByViewer = jmoldat.isColourByViewer(); - colourByViewer &= structureState - .hasColourByJmol() ? structureState + colourByViewer &= structureState.hasColourByJmol() ? structureState .getColourByJmol() : true; jmoldat.setColourByViewer(colourByViewer); @@ -3155,11 +3235,12 @@ public class Jalview2XML } } } - // Instantiate the associated structure views - for (Entry entry : structureViewers.entrySet()) + // Instantiate the associated structure views + for (Entry entry : structureViewers + .entrySet()) { - createOrLinkStructureViewer(entry, af, ap); - } + createOrLinkStructureViewer(entry, af, ap); + } } /** @@ -3206,8 +3287,8 @@ public class Jalview2XML * @param viewerData * @param af */ - protected void createChimeraViewer(Entry viewerData, - AlignFrame af) + protected void createChimeraViewer( + Entry viewerData, AlignFrame af) { final StructureViewerModel data = viewerData.getValue(); String chimeraSession = data.getStateData(); @@ -3232,12 +3313,11 @@ public class Jalview2XML boolean colourBySequence = data.isColourWithAlignPanel(); // TODO can/should this be done via StructureViewer (like Jmol)? - final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs - .size()]); - final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs.size()][]); + final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]); + final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs + .size()][]); new ChimeraViewFrame(chimeraSession, af.alignPanel, pdbArray, - seqsArray, - colourByChimera, colourBySequence); + seqsArray, colourByChimera, colourBySequence); } else { @@ -3255,7 +3335,8 @@ public class Jalview2XML * @param af */ protected void createJmolViewer( - final Entry viewerData, AlignFrame af) + final Entry viewerData, + AlignFrame af) { final StructureViewerModel svattrib = viewerData.getValue(); String state = svattrib.getStateData(); @@ -3282,8 +3363,7 @@ public class Jalview2XML newFileLoc.append(Platform.escapeString(filedat.getFilePath())); pdbfilenames.add(filedat.getFilePath()); pdbids.add(filedat.getPdbId()); - seqmaps.add(filedat.getSeqList() - .toArray(new SequenceI[0])); + seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0])); newFileLoc.append("\""); cp = ecp + 1; // advance beyond last \" and set cursor so we can // look for next file statement. @@ -3307,8 +3387,7 @@ public class Jalview2XML newFileLoc.append(filedat.getFilePath()); pdbfilenames.add(filedat.getFilePath()); pdbids.add(filedat.getPdbId()); - seqmaps.add(filedat.getSeqList() - .toArray(new SequenceI[0])); + seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0])); newFileLoc.append(" \""); newFileLoc.append(filedat.getFilePath()); newFileLoc.append("\""); @@ -3414,8 +3493,8 @@ public class Jalview2XML * Post jalview 2.4 schema includes structure view id */ if (sviewid != null - && ((StructureViewerBase) frame).getViewId().equals( - sviewid)) + && ((StructureViewerBase) frame).getViewId() + .equals(sviewid)) { comp = (AppJmol) frame; // todo: break? @@ -3600,10 +3679,10 @@ public class Jalview2XML } } - AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs, - Alignment al, JalviewModelSequence jms, Viewport view, - String uniqueSeqSetId, String viewId, - ArrayList autoAlan) + AlignFrame loadViewport(String file, JSeq[] JSEQ, + List hiddenSeqs, Alignment al, + JalviewModelSequence jms, Viewport view, String uniqueSeqSetId, + String viewId, List autoAlan) { AlignFrame af = null; af = new AlignFrame(al, view.getWidth(), view.getHeight(), @@ -3617,19 +3696,18 @@ public class Jalview2XML .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour())); } - af.viewport.gatherViewsHere = view.getGatheredViews(); + af.viewport.setGatherViewsHere(view.getGatheredViews()); if (view.getSequenceSetId() != null) { - jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded - .get(uniqueSeqSetId); + AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId); af.viewport.setSequenceSetId(uniqueSeqSetId); if (av != null) { // propagate shared settings to this new view - af.viewport.historyList = av.historyList; - af.viewport.redoList = av.redoList; + af.viewport.setHistoryList(av.getHistoryList()); + af.viewport.setRedoList(av.getRedoList()); } else { @@ -3654,14 +3732,17 @@ public class Jalview2XML af.viewport.hideRepSequences(al.getSequenceAt(s), hidden); } - jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs - .size()]; - - for (int s = 0; s < hiddenSeqs.size(); s++) - { - hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s); - } + // jalview.datamodel.SequenceI[] hseqs = new + // jalview.datamodel.SequenceI[hiddenSeqs + // .size()]; + // + // for (int s = 0; s < hiddenSeqs.size(); s++) + // { + // hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s); + // } + SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs + .size()]); af.viewport.hideSequence(hseqs); } @@ -3682,27 +3763,27 @@ public class Jalview2XML af.viewport.setConservationSelected(view.getConservationSelected()); af.viewport.setShowJVSuffix(view.getShowFullId()); af.viewport.setRightAlignIds(view.getRightAlignIds()); - af.viewport.setFont(new java.awt.Font(view.getFontName(), view - .getFontStyle(), view.getFontSize())); - af.alignPanel.fontChanged(); + af.viewport.setFont( + new java.awt.Font(view.getFontName(), view.getFontStyle(), view + .getFontSize()), true); + // TODO: allow custom charWidth/Heights to be restored by updating them + // after setting font - which means set above to false af.viewport.setRenderGaps(view.getRenderGaps()); af.viewport.setWrapAlignment(view.getWrapAlignment()); - af.alignPanel.setWrapAlignment(view.getWrapAlignment()); af.viewport.setShowAnnotation(view.getShowAnnotation()); - af.alignPanel.setAnnotationVisible(view.getShowAnnotation()); af.viewport.setShowBoxes(view.getShowBoxes()); af.viewport.setShowText(view.getShowText()); - af.viewport.textColour = new java.awt.Color(view.getTextCol1()); - af.viewport.textColour2 = new java.awt.Color(view.getTextCol2()); - af.viewport.thresholdTextColour = view.getTextColThreshold(); + af.viewport.setTextColour(new java.awt.Color(view.getTextCol1())); + af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2())); + af.viewport.setThresholdTextColour(view.getTextColThreshold()); af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view .isShowUnconserved() : false); af.viewport.setStartRes(view.getStartRes()); af.viewport.setStartSeq(view.getStartSeq()); - + af.alignPanel.updateLayout(); ColourSchemeI cs = null; // apply colourschemes if (view.getBgColour() != null) @@ -3785,11 +3866,11 @@ public class Jalview2XML } if (view.hasShowDbRefTooltip()) { - af.viewport.setShowDbRefs(view.getShowDbRefTooltip()); + af.viewport.setShowDBRefs(view.getShowDbRefTooltip()); } if (view.hasShowNPfeatureTooltip()) { - af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip()); + af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip()); } if (view.hasShowGroupConsensus()) { @@ -3910,12 +3991,27 @@ public class Jalview2XML } } af.setMenusFromViewport(af.viewport); + // TODO: we don't need to do this if the viewport is aready visible. - Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(), - view.getHeight()); - af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation - reorderAutoannotation(af, al, autoAlan); - af.alignPanel.alignmentChanged(); + /* + * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it + * has a 'cdna/protein complement' view, in which case save it in order to + * populate a SplitFrame once all views have been read in. + */ + String complementaryViewId = view.getComplementId(); + if (complementaryViewId == null) + { + Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(), + view.getHeight()); + // recompute any autoannotation + af.alignPanel.updateAnnotation(false, true); + reorderAutoannotation(af, al, autoAlan); + af.alignPanel.alignmentChanged(); + } + else + { + splitFrameCandidates.put(view, af); + } return af; } @@ -4045,7 +4141,7 @@ public class Jalview2XML } private void reorderAutoannotation(AlignFrame af, Alignment al, - ArrayList autoAlan) + List autoAlan) { // copy over visualization settings for autocalculated annotation in the // view @@ -4069,11 +4165,11 @@ public class Jalview2XML + auan.template.getCalcId()), auan); } int hSize = al.getAlignmentAnnotation().length; - ArrayList reorder = new ArrayList(); + List reorder = new ArrayList(); // work through any autoCalculated annotation already on the view // removing it if it should be placed in a different location on the // annotation panel. - List remains = new ArrayList(visan.keySet()); + List remains = new ArrayList(visan.keySet()); for (int h = 0; h < hSize; h++) { jalview.datamodel.AlignmentAnnotation jalan = al @@ -4245,9 +4341,8 @@ public class Jalview2XML { // JBP TODO: Check this is called for AlCodonFrames to support recovery of // xRef Codon Maps - jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds - .get(vamsasSeq.getId()); - jalview.datamodel.SequenceI dsq = null; + SequenceI sq = seqRefIds.get(vamsasSeq.getId()); + SequenceI dsq = null; if (sq != null && sq.getDatasetSequence() != null) { dsq = sq.getDatasetSequence(); @@ -4322,7 +4417,7 @@ public class Jalview2XML // if (pre || post) if (sq != dsq) { - StringBuffer sb = new StringBuffer(); + // StringBuffer sb = new StringBuffer(); String newres = jalview.analysis.AlignSeq.extractGaps( jalview.util.Comparison.GapChars, sq.getSequenceAsString()); if (!newres.equalsIgnoreCase(dsq.getSequenceAsString()) @@ -4472,14 +4567,14 @@ public class Jalview2XML * local sequence definition */ Sequence ms = mc.getSequence(); - jalview.datamodel.Sequence djs = null; + SequenceI djs = null; String sqid = ms.getDsseqid(); if (sqid != null && sqid.length() > 0) { /* * recover dataset sequence */ - djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid); + djs = seqRefIds.get(sqid); } else { @@ -4538,7 +4633,7 @@ public class Jalview2XML frefedSequence = new Vector(); } - viewportsAdded = new Hashtable(); + viewportsAdded.clear(); AlignFrame af = loadFromObject(jm, null, false, null); af.alignPanels.clear(); @@ -4685,13 +4780,9 @@ public class Jalview2XML } else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation) { - if (annotationIds == null) - { - annotationIds = new Hashtable(); - } String anid; - annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj); - jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj; + AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj; + annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann); if (jvann.annotationId == null) { jvann.annotationId = anid; diff --git a/src/jalview/gui/Jalview2XML_V1.java b/src/jalview/gui/Jalview2XML_V1.java index c83f1aa..ef01a50 100755 --- a/src/jalview/gui/Jalview2XML_V1.java +++ b/src/jalview/gui/Jalview2XML_V1.java @@ -371,15 +371,14 @@ public class Jalview2XML_V1 af.viewport.setColourText(view.getShowColourText()); af.viewport.setConservationSelected(view.getConservationSelected()); af.viewport.setShowJVSuffix(view.getShowFullId()); - af.viewport.setFont(new java.awt.Font(view.getFontName(), view - .getFontStyle(), view.getFontSize())); - af.alignPanel.fontChanged(); + af.viewport.setFont( + new java.awt.Font(view.getFontName(), view.getFontStyle(), view + .getFontSize()), true); af.viewport.setRenderGaps(view.getRenderGaps()); af.viewport.setWrapAlignment(view.getWrapAlignment()); - af.alignPanel.setWrapAlignment(view.getWrapAlignment()); - af.viewport.setShowAnnotation(view.getShowAnnotation()); - af.alignPanel.setAnnotationVisible(view.getShowAnnotation()); + + af.viewport.setShowAnnotation(view.isShowAnnotation()); af.viewport.setShowBoxes(view.getShowBoxes()); af.viewport.setShowText(view.getShowText()); @@ -405,6 +404,7 @@ public class Jalview2XML_V1 af.viewport.setGlobalColourScheme(cs); af.viewport.setColourAppliesToAllGroups(false); + af.alignPanel.updateLayout(); af.changeColour(cs); if (view.getConservationSelected() && cs != null) { diff --git a/src/jalview/gui/JvSwingUtils.java b/src/jalview/gui/JvSwingUtils.java index c5dd7b6..a0bc7c9 100644 --- a/src/jalview/gui/JvSwingUtils.java +++ b/src/jalview/gui/JvSwingUtils.java @@ -22,8 +22,10 @@ package jalview.gui; import jalview.util.MessageManager; +import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; +import java.awt.GridLayout; import java.awt.Rectangle; import java.awt.event.ActionListener; @@ -34,6 +36,7 @@ import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPanel; +import javax.swing.JScrollBar; import javax.swing.SwingConstants; /** @@ -122,14 +125,16 @@ public final class JvSwingUtils public static JPanel addtoLayout(JPanel panel, String tooltip, JComponent label, JComponent valBox) { - JPanel laypanel = new JPanel(), labPanel = new JPanel(), valPanel = new JPanel(); + JPanel laypanel = new JPanel(new GridLayout(1, 2)); + JPanel labPanel = new JPanel(new BorderLayout()); + JPanel valPanel = new JPanel(); // laypanel.setSize(panel.getPreferredSize()); // laypanel.setLayout(null); labPanel.setBounds(new Rectangle(7, 7, 158, 23)); valPanel.setBounds(new Rectangle(172, 7, 270, 23)); // labPanel.setLayout(new GridLayout(1,1)); // valPanel.setLayout(new GridLayout(1,1)); - labPanel.add(label); + labPanel.add(label, BorderLayout.WEST); valPanel.add(valBox); laypanel.add(labPanel); laypanel.add(valPanel); @@ -212,6 +217,53 @@ public final class JvSwingUtils } } + /** + * Returns the proportion of its range that a scrollbar's position represents, + * as a value between 0 and 1. For example if the whole range is from 0 to + * 200, then a position of 40 gives proportion = 0.2. + * + * @see http://www.javalobby.org/java/forums/t33050.html#91885334 + * + * @param scroll + * @return + */ + public static float getScrollBarProportion(JScrollBar scroll) + { + /* + * The extent (scroll handle width) deduction gives the true operating range + * of possible positions. + */ + int possibleRange = scroll.getMaximum() - scroll.getMinimum() + - scroll.getModel().getExtent(); + float valueInRange = scroll.getValue() + - (scroll.getModel().getExtent() / 2f); + float proportion = valueInRange / possibleRange; + return proportion; + } + + /** + * Returns the scroll bar position in its range that would match the given + * proportion (between 0 and 1) of the whole. For example if the whole range + * is from 0 to 200, then a proportion of 0.25 gives position 50. + * + * @param scrollbar + * @param proportion + * @return + */ + public static int getScrollValueForProportion(JScrollBar scrollbar, + float proportion) + { + /* + * The extent (scroll handle width) deduction gives the true operating range + * of possible positions. + */ + float fraction = proportion + * (scrollbar.getMaximum() - scrollbar.getMinimum() - scrollbar + .getModel().getExtent()) + + (scrollbar.getModel().getExtent() / 2f); + return Math.min(Math.round(fraction), scrollbar.getMaximum()); + } + public static void jvInitComponent(AbstractButton comp, String i18nString) { setColorAndFont(comp); diff --git a/src/jalview/gui/OverviewPanel.java b/src/jalview/gui/OverviewPanel.java index bed9de1..39a232a 100755 --- a/src/jalview/gui/OverviewPanel.java +++ b/src/jalview/gui/OverviewPanel.java @@ -22,10 +22,17 @@ package jalview.gui; import jalview.renderer.AnnotationRenderer; -import java.awt.*; -import java.awt.event.*; -import java.awt.image.*; -import javax.swing.*; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.awt.image.BufferedImage; + +import javax.swing.JPanel; /** * DOCUMENT ME! @@ -135,7 +142,7 @@ public class OverviewPanel extends JPanel implements Runnable @Override public void mouseDragged(MouseEvent evt) { - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { // TODO: feature: jv2.5 detect shift drag and update selection from // it. @@ -151,7 +158,7 @@ public class OverviewPanel extends JPanel implements Runnable @Override public void mousePressed(MouseEvent evt) { - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { boxX = evt.getX(); boxY = evt.getY(); diff --git a/src/jalview/gui/PCAPanel.java b/src/jalview/gui/PCAPanel.java index b879092..2674617 100644 --- a/src/jalview/gui/PCAPanel.java +++ b/src/jalview/gui/PCAPanel.java @@ -28,6 +28,7 @@ import jalview.datamodel.SequenceI; import jalview.jbgui.GPCAPanel; import jalview.schemes.ResidueProperties; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import jalview.viewmodel.PCAModel; import java.awt.BorderLayout; @@ -67,7 +68,7 @@ public class PCAPanel extends GPCAPanel implements Runnable, AlignmentPanel ap; - AlignViewport av; + AlignmentViewport av; PCAModel pcaModel; diff --git a/src/jalview/gui/PDBSearchPanel.java b/src/jalview/gui/PDBSearchPanel.java new file mode 100644 index 0000000..2d46714 --- /dev/null +++ b/src/jalview/gui/PDBSearchPanel.java @@ -0,0 +1,173 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2) + * Copyright (C) 2014 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 . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ + +package jalview.gui; + +import jalview.jbgui.GPDBSearchPanel; +import jalview.jbgui.PDBDocFieldPreferences; +import jalview.util.MessageManager; +import jalview.ws.dbsources.PDBRestClient; +import jalview.ws.dbsources.PDBRestClient.PDBDocField; +import jalview.ws.uimodel.PDBRestRequest; +import jalview.ws.uimodel.PDBRestResponse; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import javax.swing.table.DefaultTableModel; + +@SuppressWarnings("serial") +public class PDBSearchPanel extends GPDBSearchPanel +{ + private SequenceFetcher seqFetcher; + + private IProgressIndicator progressIdicator; + + private Collection wantedFields; + + public PDBSearchPanel(SequenceFetcher seqFetcher) + { + this.seqFetcher = seqFetcher; + this.progressIdicator = (seqFetcher == null) ? null : seqFetcher + .getProgressIndicator(); + } + + + /** + * Action performed when an input is detected on txt_search field. + */ + @Override + public void txt_search_ActionPerformed() + { + boolean allowEmptySequence = false; + mainFrame.setTitle(MessageManager + .getString("label.pdb_sequence_getcher")); + tbl_summary.setModel(new DefaultTableModel()); + if (txt_search.getText().trim().length() > 0) + { + long startTime = System.currentTimeMillis(); + + String searchTarget = ((PDBDocField) cmb_searchTarget + .getSelectedItem()).getCode(); + + wantedFields = PDBDocFieldPreferences + .getSearchSummaryFields(); + + PDBRestRequest request = new PDBRestRequest(); + request.setAllowEmptySeq(allowEmptySequence); + request.setResponseSize(100); + request.setFieldToSearchBy(searchTarget + ":"); + request.setSearchTerm(txt_search.getText()); + request.setWantedFields(wantedFields); + + PDBRestClient pdbRestCleint = new PDBRestClient(); + PDBRestResponse resultList = pdbRestCleint.executeRequest(request); + if (resultList.getSearchSummary() != null) + { + tbl_summary.setModel(PDBRestResponse.getTableModel(request, + resultList.getSearchSummary())); + } + + long endTime = System.currentTimeMillis(); + int resultSetCount = resultList.getNumberOfItemsFound(); + String result = (resultSetCount > 1) ? MessageManager + .getString("label.results") : MessageManager + .getString("label.result"); + mainFrame.setTitle(frameTitle + " - " + resultSetCount + " " + result + + " (" + (endTime - startTime) + " milli secs)"); + } + } + + @Override + public void btn_ok_ActionPerformed() + { + loadSelectedPDBSequencesToAlignment(); + } + + @Override + public void btn_back_ActionPerformed() + { + mainFrame.dispose(); + new SequenceFetcher(progressIdicator); + } + + @Override + public void btn_cancel_ActionPerformed() + { + mainFrame.dispose(); + } + + /** + * Add the discovered/selected sequences to a target alignment window + */ + public void loadSelectedPDBSequencesToAlignment() + { + mainFrame.dispose(); + StringBuilder selectedIds = new StringBuilder(); + int pdbIdCol = PDBRestClient.getPDBIdColumIndex(wantedFields, false); + int[] selectedRows = tbl_summary.getSelectedRows(); + for (int summaryRow : selectedRows) + { + String pdbIdStr = tbl_summary.getValueAt(summaryRow, pdbIdCol) + .toString(); + selectedIds.append(";").append(pdbIdStr); + } + + String ids = selectedIds.deleteCharAt(0).toString(); + seqFetcher.textArea.setText(ids); + Thread worker = new Thread(seqFetcher); + worker.start(); + } + + /** + * Populates search target combo-box options + */ + public void populateCmbSearchTargetOptions() + { + List searchableTargets = new ArrayList(); + searchableTargets.add(PDBDocField.PDB_ID); + searchableTargets.add(PDBDocField.PFAM_ACCESSION); + searchableTargets.add(PDBDocField.MOLECULE_TYPE); + searchableTargets.add(PDBDocField.MOLECULE_NAME); + searchableTargets.add(PDBDocField.UNIPROT_ACCESSION); + searchableTargets.add(PDBDocField.GENE_NAME); + searchableTargets.add(PDBDocField.GENUS); + searchableTargets.add(PDBDocField.ALL); + + Collections.sort(searchableTargets, new Comparator() + { + @Override + public int compare(PDBDocField o1, PDBDocField o2) + { + return o1.getName().compareTo(o2.getName()); + } + }); + + for (PDBDocField searchTarget : searchableTargets) + { + cmb_searchTarget.addItem(searchTarget); + } + } + +} diff --git a/src/jalview/gui/PaintRefresher.java b/src/jalview/gui/PaintRefresher.java index b6d5a41..b129971 100755 --- a/src/jalview/gui/PaintRefresher.java +++ b/src/jalview/gui/PaintRefresher.java @@ -20,12 +20,15 @@ */ package jalview.gui; -import java.util.*; -import java.util.List; - -import java.awt.*; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SequenceI; -import jalview.datamodel.*; +import java.awt.Component; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; /** * Route datamodel/view update events for a sequence set to any display @@ -36,57 +39,61 @@ import jalview.datamodel.*; */ public class PaintRefresher { - static Hashtable components; + static Map> components = new HashMap>(); /** - * DOCUMENT ME! + * Add the given component to those registered under the given sequence set + * id. Does nothing if already added. * * @param comp - * DOCUMENT ME! * @param al - * DOCUMENT ME! */ public static void Register(Component comp, String seqSetId) { - if (components == null) - { - components = new Hashtable(); - } - if (components.containsKey(seqSetId)) { - Vector comps = (Vector) components.get(seqSetId); + List comps = components.get(seqSetId); if (!comps.contains(comp)) { - comps.addElement(comp); + comps.add(comp); } } else { - Vector vcoms = new Vector(); - vcoms.addElement(comp); + List vcoms = new ArrayList(); + vcoms.add(comp); components.put(seqSetId, vcoms); } } + /** + * Remove this component from all registrations. Also removes a registered + * sequence set id if there are no remaining components registered against it. + * + * @param comp + */ public static void RemoveComponent(Component comp) { - if (components == null) - { - return; - } - - Enumeration en = components.keys(); - while (en.hasMoreElements()) + List emptied = new ArrayList(); + for (Entry> registered : components.entrySet()) { - String id = en.nextElement().toString(); - Vector comps = (Vector) components.get(id); + String id = registered.getKey(); + List comps = components.get(id); comps.remove(comp); - if (comps.size() == 0) + if (comps.isEmpty()) { - components.remove(id); + emptied.add(id); } } + + /* + * Remove now empty ids after the above (to avoid + * ConcurrentModificationException). + */ + for (String id : emptied) + { + components.remove(id); + } } public static void Refresh(Component source, String id) @@ -97,24 +104,15 @@ public class PaintRefresher public static void Refresh(Component source, String id, boolean alignmentChanged, boolean validateSequences) { - if (components == null) - { - return; - } - - Component comp; - Vector comps = (Vector) components.get(id); + List comps = components.get(id); if (comps == null) { return; } - Enumeration e = comps.elements(); - while (e.hasMoreElements()) + for (Component comp : comps) { - comp = (Component) e.nextElement(); - if (comp == source) { continue; @@ -242,30 +240,20 @@ public class PaintRefresher static AlignmentPanel[] getAssociatedPanels(String id) { - if (components == null) - { - return new AlignmentPanel[0]; - } - ; - Vector comps = (Vector) components.get(id); + List comps = components.get(id); if (comps == null) { return new AlignmentPanel[0]; } - ; - Vector tmp = new Vector(); - int i, iSize = comps.size(); - for (i = 0; i < iSize; i++) + List tmp = new ArrayList(); + for (Component comp : comps) { - if (comps.elementAt(i) instanceof AlignmentPanel) + if (comp instanceof AlignmentPanel) { - tmp.addElement(comps.elementAt(i)); + tmp.add((AlignmentPanel) comp); } } - AlignmentPanel[] result = new AlignmentPanel[tmp.size()]; - tmp.toArray(result); - - return result; + return tmp.toArray(new AlignmentPanel[tmp.size()]); } } diff --git a/src/jalview/gui/PairwiseAlignPanel.java b/src/jalview/gui/PairwiseAlignPanel.java index 66ceffe..22f1368 100755 --- a/src/jalview/gui/PairwiseAlignPanel.java +++ b/src/jalview/gui/PairwiseAlignPanel.java @@ -26,6 +26,7 @@ import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; import jalview.jbgui.GPairwiseAlignPanel; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.awt.event.ActionEvent; import java.util.Vector; @@ -39,7 +40,7 @@ import java.util.Vector; public class PairwiseAlignPanel extends GPairwiseAlignPanel { - AlignViewport av; + AlignmentViewport av; Vector sequences; @@ -49,7 +50,7 @@ public class PairwiseAlignPanel extends GPairwiseAlignPanel * @param av * DOCUMENT ME! */ - public PairwiseAlignPanel(AlignViewport av) + public PairwiseAlignPanel(AlignmentViewport av) { super(); this.av = av; diff --git a/src/jalview/gui/PopupMenu.java b/src/jalview/gui/PopupMenu.java index 7878f75..1263b71 100644 --- a/src/jalview/gui/PopupMenu.java +++ b/src/jalview/gui/PopupMenu.java @@ -20,8 +20,30 @@ */ package jalview.gui; +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Arrays; +import java.util.Collections; +import java.util.Hashtable; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.Vector; + +import javax.swing.ButtonGroup; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JColorChooser; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPopupMenu; +import javax.swing.JRadioButtonMenuItem; + import jalview.analysis.AAFrequency; import jalview.analysis.AlignmentAnnotationUtils; +import jalview.analysis.AlignmentUtils; import jalview.analysis.Conservation; import jalview.commands.ChangeCaseCommand; import jalview.commands.EditCommand; @@ -58,29 +80,6 @@ import jalview.util.GroupUrlLink.UrlStringTooLongException; import jalview.util.MessageManager; import jalview.util.UrlLink; -import java.awt.Color; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Hashtable; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import java.util.Vector; - -import javax.swing.ButtonGroup; -import javax.swing.JCheckBoxMenuItem; -import javax.swing.JColorChooser; -import javax.swing.JMenu; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPopupMenu; -import javax.swing.JRadioButtonMenuItem; - /** * DOCUMENT ME! * @@ -125,9 +124,6 @@ public class PopupMenu extends JPopupMenu protected JRadioButtonMenuItem RNAInteractionColour = new JRadioButtonMenuItem(); - // protected JRadioButtonMenuItem covariationColour = new - // JRadioButtonMenuItem(); - JRadioButtonMenuItem noColourmenuItem = new JRadioButtonMenuItem(); protected JCheckBoxMenuItem conservationMenuItem = new JCheckBoxMenuItem(); @@ -182,12 +178,6 @@ public class PopupMenu extends JPopupMenu JMenuItem pdbFromFile = new JMenuItem(); - // JBPNote: Commented these out - Should add these services via the web - // services menu system. - // JMenuItem ContraFold = new JMenuItem(); - - // JMenuItem RNAFold = new JMenuItem(); - JMenuItem enterPDB = new JMenuItem(); JMenuItem discoverPDB = new JMenuItem(); @@ -198,13 +188,15 @@ public class PopupMenu extends JPopupMenu JMenu seqHideAnnotationsMenu = new JMenu(); - JMenuItem seqAddReferenceAnnotations = new JMenuItem(); + JMenuItem seqAddReferenceAnnotations = new JMenuItem( + MessageManager.getString("label.add_reference_annotations")); JMenu groupShowAnnotationsMenu = new JMenu(); JMenu groupHideAnnotationsMenu = new JMenu(); - JMenuItem groupAddReferenceAnnotations = new JMenuItem(); + JMenuItem groupAddReferenceAnnotations = new JMenuItem( + MessageManager.getString("label.add_reference_annotations")); JMenuItem sequenceFeature = new JMenuItem(); @@ -212,15 +204,12 @@ public class PopupMenu extends JPopupMenu JMenu jMenu1 = new JMenu(); - JMenu structureMenu = new JMenu(); + JMenuItem structureMenu = new JMenuItem(); JMenu viewStructureMenu = new JMenu(); - // JMenu colStructureMenu = new JMenu(); JMenuItem editSequence = new JMenuItem(); - // JMenuItem annotationMenuItem = new JMenuItem(); - JMenu groupLinksMenu; JMenuItem hideInsertions = new JMenuItem(); @@ -273,7 +262,6 @@ public class PopupMenu extends JPopupMenu colours.add(BLOSUM62Colour); colours.add(purinePyrimidineColour); colours.add(RNAInteractionColour); - // colours.add(covariationColour); for (int i = 0; i < jalview.io.FormatAdapter.WRITEABLE_FORMATS.length; i++) { @@ -378,7 +366,6 @@ public class PopupMenu extends JPopupMenu { structureMenu.remove(viewStructureMenu); } - // structureMenu.remove(colStructureMenu); } if (ap.av.getAlignment().isNucleotide() == true) { @@ -392,26 +379,15 @@ public class PopupMenu extends JPopupMenu final String structureLine = aa[i].label + " (alignment)"; menuItem = new JMenuItem(); menuItem.setText(MessageManager.formatMessage( - "label.2d_rna_structure_line", new String[] + "label.2d_rna_structure_line", new Object[] { structureLine })); menuItem.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(ActionEvent e) { - // // System.out.println("1:"+structureLine); - // System.out.println("1:sname" + seq.getName()); - // System.out.println("2:seq" + seq); - // - // // System.out.println("3:"+seq.getSequenceAsString()); - // System.out.println("3:strucseq" + rnastruc); - // // System.out.println("4:struc"+seq.getRNA()); - // System.out.println("5:name" + seq.getName()); - // System.out.println("6:ap" + ap); new AppVarna(structureLine, seq, seq.getSequenceAsString(), rnastruc, seq.getName(), ap); - // new AppVarna(seq.getName(),seq,rnastruc,seq.getRNA(), - // seq.getName(), ap); System.out.println("end"); } }); @@ -419,7 +395,6 @@ public class PopupMenu extends JPopupMenu } } - // SequenceFeatures[] test = seq.getSequenceFeatures(); if (seq.getAnnotation() != null) { @@ -433,7 +408,7 @@ public class PopupMenu extends JPopupMenu // TODO: make rnastrucF a bit more nice menuItem = new JMenuItem(); menuItem.setText(MessageManager.formatMessage( - "label.2d_rna_sequence_name", new String[] + "label.2d_rna_sequence_name", new Object[] { seq.getName() })); menuItem.addActionListener(new java.awt.event.ActionListener() { @@ -469,7 +444,7 @@ public class PopupMenu extends JPopupMenu && ap.av.getSelectionGroup().getSize() > 1) { menuItem = new JMenuItem(MessageManager.formatMessage( - "label.represent_group_with", new String[] + "label.represent_group_with", new Object[] { seq.getName() })); menuItem.addActionListener(new java.awt.event.ActionListener() { @@ -538,7 +513,7 @@ public class PopupMenu extends JPopupMenu if (sg != null && sg.getSize() > 0) { groupName.setText(MessageManager.formatMessage("label.name_param", - new String[] + new Object[] { sg.getName() })); groupName.setText(MessageManager .getString("label.edit_name_and_description_current_group")); @@ -639,50 +614,6 @@ public class PopupMenu extends JPopupMenu new PDBEntry[pdbe.size()]), pr = reppdb.values().toArray( new PDBEntry[reppdb.size()]); final JMenuItem gpdbview, rpdbview; - if (pdbe.size() == 1) - { - structureMenu.add(gpdbview = new JMenuItem(MessageManager - .formatMessage("label.view_structure_for", new String[] - { sqass.getDisplayId(false) }))); - } - else - { - structureMenu.add(gpdbview = new JMenuItem(MessageManager - .formatMessage("label.view_all_structures", new String[] - { new Integer(pdbe.size()).toString() }))); - } - gpdbview.setToolTipText(MessageManager - .getString("label.open_new_jmol_view_with_all_structures_associated_current_selection_superimpose_using_alignment")); - gpdbview.addActionListener(new ActionListener() - { - - @Override - public void actionPerformed(ActionEvent e) - { - new StructureViewer(ap.getStructureSelectionManager()) - .viewStructures(ap, pe, ap.av.collateForPDB(pe)); - } - }); - if (reppdb.size() > 1 && reppdb.size() < pdbe.size()) - { - structureMenu.add(rpdbview = new JMenuItem(MessageManager - .formatMessage( - "label.view_all_representative_structures", - new String[] - { new Integer(reppdb.size()).toString() }))); - rpdbview.setToolTipText(MessageManager - .getString("label.open_new_jmol_view_with_all_representative_structures_associated_current_selection_superimpose_using_alignment")); - rpdbview.addActionListener(new ActionListener() - { - - @Override - public void actionPerformed(ActionEvent e) - { - new StructureViewer(ap.getStructureSelectionManager()) - .viewStructures(ap, pr, ap.av.collateForPDB(pr)); - } - }); - } } } else @@ -946,7 +877,7 @@ public class PopupMenu extends JPopupMenu final boolean actionIsShow) { String label = types.toString(); // [a, b, c] - label = label.substring(1, label.length() - 1); + label = label.substring(1, label.length() - 1); // a, b, c final JMenuItem item = new JMenuItem(label); item.setToolTipText(calcId); item.addActionListener(new java.awt.event.ActionListener() @@ -954,41 +885,14 @@ public class PopupMenu extends JPopupMenu @Override public void actionPerformed(ActionEvent e) { - showHideAnnotation_actionPerformed(types, forSequences, allTypes, - actionIsShow); + AlignmentUtils.showOrHideSequenceAnnotations(ap.getAlignment(), types, + forSequences, allTypes, actionIsShow); + refresh(); } }); showOrHideMenu.add(item); } - /** - * Action on selecting a list of annotation type (or the 'all types' values) - * to show or hide for the specified sequences. - * - * @param types - * @param forSequences - * @param anyType - * @param doShow - */ - protected void showHideAnnotation_actionPerformed( - Collection types, List forSequences, - boolean anyType, boolean doShow) - { - for (AlignmentAnnotation aa : ap.getAlignment() - .getAlignmentAnnotation()) - { - if (anyType || types.contains(aa.label)) - { - if ((aa.sequenceRef != null) - && forSequences.contains(aa.sequenceRef)) - { - aa.visible = doShow; - } - } - } - refresh(); - } - private void buildGroupURLMenu(SequenceGroup sg, Vector groupLinks) { @@ -1116,8 +1020,6 @@ public class PopupMenu extends JPopupMenu if (urlset != null) { int type = urlLink.getGroupURLType() & 3; - // System.out.println(urlLink.getGroupURLType() - // +" "+((String[])urlset[3])[0]); // first two bits ofurlLink type bitfield are sequenceids and sequences // TODO: FUTURE: ensure the groupURL menu structure can be generalised addshowLink(linkMenus[type], label @@ -1157,7 +1059,7 @@ public class PopupMenu extends JPopupMenu { JMenuItem item = new JMenuItem(label); item.setToolTipText(MessageManager.formatMessage( - "label.open_url_param", new String[] + "label.open_url_param", new Object[] { url })); item.addActionListener(new java.awt.event.ActionListener() { @@ -1428,32 +1330,7 @@ public class PopupMenu extends JPopupMenu pdbFromFile_actionPerformed(); } }); - // RNAFold.setText("From RNA Fold with predict2D"); - // RNAFold.addActionListener(new ActionListener() - // { - // public void actionPerformed(ActionEvent e) - // { - // try { - // RNAFold_actionPerformed(); - // } catch (Exception e1) { - // // TODO Auto-generated catch block - // e1.printStackTrace(); - // } - // } - // }); - // ContraFold.setText("From Contra Fold with predict2D"); - // ContraFold.addActionListener(new ActionListener() - // { - // public void actionPerformed(ActionEvent e) - // { - // try { - // ContraFold_actionPerformed(); - // } catch (Exception e1) { - // // TODO Auto-generated catch block - // e1.printStackTrace(); - // } - // } - // }); + enterPDB.setText(MessageManager.getString("label.enter_pdb_id")); enterPDB.addActionListener(new ActionListener() { @@ -1502,7 +1379,22 @@ public class PopupMenu extends JPopupMenu } }); jMenu1.setText(MessageManager.getString("label.group")); - structureMenu.setText(MessageManager.getString("label.structure")); + structureMenu.setText(MessageManager.getString("label.view_structure")); + structureMenu.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + SequenceI[] selectedSeqs = new SequenceI[] + { sequence }; + if (ap.av.getSelectionGroup() != null) + { + selectedSeqs = ap.av.getSequenceSelection(); + } + new StructureChooser(selectedSeqs, sequence, ap); + } + }); + viewStructureMenu.setText(MessageManager .getString("label.view_structure")); // colStructureMenu.setText("Colour By Structure"); @@ -1590,10 +1482,8 @@ public class PopupMenu extends JPopupMenu if (ap.getAlignment().isNucleotide()) { // JBPNote - commented since the colourscheme isn't functional - // colourMenu.add(RNAInteractionColour); colourMenu.add(purinePyrimidineColour); } - // colourMenu.add(covariationColour); colourMenu.add(userDefinedColour); if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null) @@ -1619,7 +1509,6 @@ public class PopupMenu extends JPopupMenu colourMenu.addSeparator(); colourMenu.add(abovePIDColour); colourMenu.add(conservationMenuItem); - // colourMenu.add(annotationMenuItem); editMenu.add(copy); editMenu.add(cut); editMenu.add(editSequence); @@ -1640,9 +1529,6 @@ public class PopupMenu extends JPopupMenu jMenu1.add(showColourText); jMenu1.add(outline); jMenu1.add(displayNonconserved); - structureMenu.add(pdbMenu); - structureMenu.add(viewStructureMenu); - // structureMenu.add(colStructureMenu); noColourmenuItem.setText(MessageManager.getString("label.none")); noColourmenuItem.addActionListener(new java.awt.event.ActionListener() { @@ -1815,68 +1701,22 @@ public class PopupMenu extends JPopupMenu protected void configureReferenceAnnotationsMenu( JMenuItem menuItem, List forSequences) { - menuItem.setText(MessageManager - .getString("label.add_reference_annotations")); menuItem.setEnabled(false); - if (forSequences == null) - { - return; - } /* * Temporary store to hold distinct calcId / type pairs for the tooltip. * Using TreeMap means calcIds are shown in alphabetical order. */ Map tipEntries = new TreeMap(); - StringBuilder tooltip = new StringBuilder(64); - tooltip.append(MessageManager.getString("label.add_annotations_for")); - - /* - * For each sequence selected in the alignment, make a list of any - * annotations on the underlying dataset sequence which are not already on - * the alignment. - * - * Build a map of { alignmentSequence, } - */ - AlignmentI al = this.ap.av.getAlignment(); final Map> candidates = new LinkedHashMap>(); - for (SequenceI seq : forSequences) - { - SequenceI dataset = seq.getDatasetSequence(); - if (dataset == null) - { - continue; - } - AlignmentAnnotation[] datasetAnnotations = dataset.getAnnotation(); - if (datasetAnnotations == null) - { - continue; - } - final List result = new ArrayList(); - for (AlignmentAnnotation dsann : datasetAnnotations) - { - /* - * Find matching annotations on the alignment. - */ - final Iterable matchedAlignmentAnnotations = al - .findAnnotations(seq, dsann.getCalcId(), - dsann.label); - if (!matchedAlignmentAnnotations.iterator().hasNext()) - { - result.add(dsann); - tipEntries.put(dsann.getCalcId(), dsann.label); - } - } - /* - * Save any addable annotations for this sequence - */ - if (!result.isEmpty()) - { - candidates.put(seq, result); - } - } + AlignmentI al = this.ap.av.getAlignment(); + AlignmentUtils.findAddableReferenceAnnotations(forSequences, + tipEntries, candidates, al); if (!candidates.isEmpty()) { + StringBuilder tooltip = new StringBuilder(64); + tooltip.append(MessageManager.getString("label.add_annotations_for")); + /* * Found annotations that could be added. Enable the menu item, and * configure its tooltip and action. @@ -1911,40 +1751,10 @@ public class PopupMenu extends JPopupMenu protected void addReferenceAnnotations_actionPerformed( Map> candidates) { - /* - * Add annotations at the top of the annotation, in the same order as their - * related sequences. - */ - for (SequenceI seq : candidates.keySet()) - { - for (AlignmentAnnotation ann : candidates.get(seq)) - { - AlignmentAnnotation copyAnn = new AlignmentAnnotation(ann); - int startRes = 0; - int endRes = ann.annotations.length; - final SequenceGroup selectionGroup = this.ap.av.getSelectionGroup(); - if (selectionGroup != null) - { - startRes = selectionGroup.getStartRes(); - endRes = selectionGroup.getEndRes(); - } - copyAnn.restrict(startRes, endRes); - - /* - * Add to the sequence (sets copyAnn.datasetSequence), unless the - * original annotation is already on the sequence. - */ - if (!seq.hasAnnotation(ann)) - { - seq.addAlignmentAnnotation(copyAnn); - } - // adjust for gaps - copyAnn.adjustForAlignment(); - // add to the alignment and set visible - this.ap.getAlignment().addAnnotation(copyAnn); - copyAnn.visible = true; - } - } + final SequenceGroup selectionGroup = this.ap.av.getSelectionGroup(); + final AlignmentI alignment = this.ap.getAlignment(); + AlignmentUtils.addReferenceAnnotations(candidates, alignment, + selectionGroup); refresh(); } @@ -2006,7 +1816,7 @@ public class PopupMenu extends JPopupMenu + MessageManager .formatMessage( "label.create_sequence_details_report_annotation_for", - new String[] + new Object[] { seq.getDisplayId(true) }) + "

"); new SequenceAnnotationReport(null) .createSequenceAnnotationReport( @@ -2023,10 +1833,10 @@ public class PopupMenu extends JPopupMenu } cap.setText("" + contents.toString() + ""); - Desktop.instance.addInternalFrame(cap, MessageManager.formatMessage( - "label.sequece_details_for", - (sequences.length == 1 ? new String[] - { sequences[0].getDisplayId(true) } : new String[] + Desktop.addInternalFrame(cap, MessageManager.formatMessage( + "label.sequence_details_for", + (sequences.length == 1 ? new Object[] + { sequences[0].getDisplayId(true) } : new Object[] { MessageManager.getString("label.selection") })), 500, 400); } @@ -2190,14 +2000,14 @@ public class PopupMenu extends JPopupMenu int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs, getGroup() .getName()); - sg.cs.setThreshold(threshold, ap.av.getIgnoreGapsConsensus()); + sg.cs.setThreshold(threshold, ap.av.isIgnoreGapsConsensus()); SliderPanel.showPIDSlider(); } else // remove PIDColouring { - sg.cs.setThreshold(0, ap.av.getIgnoreGapsConsensus()); + sg.cs.setThreshold(0, ap.av.isIgnoreGapsConsensus()); } refresh(); @@ -2548,15 +2358,7 @@ public class PopupMenu extends JPopupMenu } int gsize = sg.getSize(); - SequenceI[] hseqs; - - hseqs = new SequenceI[gsize]; - - int index = 0; - for (int i = 0; i < gsize; i++) - { - hseqs[index++] = sg.getSequenceAt(i); - } + SequenceI[] hseqs = sg.getSequences().toArray(new SequenceI[gsize]); ap.av.hideSequence(hseqs); // refresh(); TODO: ? needed ? @@ -2580,7 +2382,8 @@ public class PopupMenu extends JPopupMenu if (sg != null) { - int[][] startEnd = ap.av.getVisibleRegionBoundaries(sg.getStartRes(), + List startEnd = ap.av.getVisibleRegionBoundaries( + sg.getStartRes(), sg.getEndRes() + 1); String description; @@ -2619,7 +2422,7 @@ public class PopupMenu extends JPopupMenu CutAndPasteTransfer cap = new CutAndPasteTransfer(); cap.setForInput(null); Desktop.addInternalFrame(cap, MessageManager.formatMessage( - "label.alignment_output_command", new String[] + "label.alignment_output_command", new Object[] { e.getActionCommand() }), 600, 500); String[] omitHidden = null; @@ -2638,10 +2441,10 @@ public class PopupMenu extends JPopupMenu jalview.bin.Cache.getProperty("LAST_DIRECTORY")); chooser.setFileView(new jalview.io.JalviewFileView()); chooser.setDialogTitle(MessageManager.formatMessage( - "label.select_pdb_file_for", new String[] + "label.select_pdb_file_for", new Object[] { sequence.getDisplayId(false) })); chooser.setToolTipText(MessageManager.formatMessage( - "label.load_pdb_file_associate_with_sequence", new String[] + "label.load_pdb_file_associate_with_sequence", new Object[] { sequence.getDisplayId(false) })); int value = chooser.showOpenDialog(null); @@ -2657,18 +2460,7 @@ public class PopupMenu extends JPopupMenu } - // JBNote: commented out - these won't be instantiated here...! - // public void RNAFold_actionPerformed() throws Exception - // { - // Predict2D P2D = new Predict2D(); - // P2D.getStructure2DFromRNAFold("toto"); - // } - // - // public void ContraFold_actionPerformed() throws Exception - // { - // Predict2D P2D = new Predict2D(); - // P2D.getStructure2DFromContraFold("toto"); - // } + public void enterPDB_actionPerformed() { String id = JOptionPane.showInternalInputDialog(Desktop.desktop, diff --git a/src/jalview/gui/Preferences.java b/src/jalview/gui/Preferences.java index ef7ca27..2a24491 100755 --- a/src/jalview/gui/Preferences.java +++ b/src/jalview/gui/Preferences.java @@ -62,6 +62,12 @@ import ext.edu.ucsf.rbvi.strucviz2.StructureManager; public class Preferences extends GPreferences { + public static final String DEFAULT_COLOUR = "DEFAULT_COLOUR"; + + public static final String DEFAULT_COLOUR_PROT = "DEFAULT_COLOUR_PROT"; + + public static final String DEFAULT_COLOUR_NUC = "DEFAULT_COLOUR_NUC"; + public static final String ADD_TEMPFACT_ANN = "ADD_TEMPFACT_ANN"; public static final String ADD_SS_ANN = "ADD_SS_ANN"; @@ -267,10 +273,14 @@ public class Preferences extends GPreferences */ for (int i = ColourSchemeProperty.FIRST_COLOUR; i <= ColourSchemeProperty.LAST_COLOUR; i++) { - colour.addItem(ColourSchemeProperty.getColourName(i)); + protColour.addItem(ColourSchemeProperty.getColourName(i)); + nucColour.addItem(ColourSchemeProperty.getColourName(i)); } - String string = Cache.getDefault("DEFAULT_COLOUR", "None"); - colour.setSelectedItem(string); + String oldProp = Cache.getDefault(DEFAULT_COLOUR, "None"); + String newProp = Cache.getDefault(DEFAULT_COLOUR_PROT, null); + protColour.setSelectedItem(newProp != null ? newProp : oldProp); + newProp = Cache.getDefault(DEFAULT_COLOUR_NUC, null); + nucColour.setSelectedItem(newProp != null ? newProp : oldProp); minColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange)); maxColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", @@ -452,7 +462,9 @@ public class Preferences extends GPreferences /* * Save Colours settings */ - Cache.applicationProperties.setProperty("DEFAULT_COLOUR", colour + Cache.applicationProperties.setProperty(DEFAULT_COLOUR_PROT, protColour + .getSelectedItem().toString()); + Cache.applicationProperties.setProperty(DEFAULT_COLOUR_NUC, nucColour .getSelectedItem().toString()); Cache.setColourProperty("ANNOTATIONCOLOUR_MIN", minColour.getBackground()); diff --git a/src/jalview/gui/RedundancyPanel.java b/src/jalview/gui/RedundancyPanel.java index eac0d46..e541540 100755 --- a/src/jalview/gui/RedundancyPanel.java +++ b/src/jalview/gui/RedundancyPanel.java @@ -276,10 +276,10 @@ public class RedundancyPanel extends GSliderPanel implements Runnable } CommandI command = historyList.pop(); - if (ap.av.historyList.contains(command)) + if (ap.av.getHistoryList().contains(command)) { command.undoCommand(af.getViewAlignments()); - ap.av.historyList.remove(command); + ap.av.getHistoryList().remove(command); ap.av.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences()); af.updateEditMenuBar(); } diff --git a/src/jalview/gui/RotatableCanvas.java b/src/jalview/gui/RotatableCanvas.java index 7a79636..4241c5f 100755 --- a/src/jalview/gui/RotatableCanvas.java +++ b/src/jalview/gui/RotatableCanvas.java @@ -30,6 +30,7 @@ import jalview.api.RotatableCanvasI; import jalview.datamodel.*; import jalview.math.*; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; /** * DOCUMENT ME! @@ -101,7 +102,7 @@ public class RotatableCanvas extends JPanel implements MouseListener, float scalefactor = 1; - AlignViewport av; + AlignmentViewport av; AlignmentPanel ap; diff --git a/src/jalview/gui/ScalePanel.java b/src/jalview/gui/ScalePanel.java index 6ef5222..519f2e2 100755 --- a/src/jalview/gui/ScalePanel.java +++ b/src/jalview/gui/ScalePanel.java @@ -423,6 +423,8 @@ public class ScalePanel extends JPanel implements MouseMotionListener, // Fill the selected columns ColumnSelection cs = av.getColumnSelection(); + int avCharWidth = av.getCharWidth(), avCharHeight = av.getCharHeight(); + int s; if (cs != null) { @@ -445,7 +447,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener, if ((sel >= startx) && (sel <= endx)) { - gg.fillRect((sel - startx) * av.charWidth, 0, av.charWidth, + gg.fillRect((sel - startx) * avCharWidth, 0, avCharWidth, getHeight()); } } @@ -456,7 +458,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener, int scalestartx = (startx / 10) * 10; FontMetrics fm = gg.getFontMetrics(av.getFont()); - int y = av.charHeight - fm.getDescent(); + int y = avCharHeight - fm.getDescent(); if ((scalestartx % 10) == 0) { @@ -472,26 +474,22 @@ public class ScalePanel extends JPanel implements MouseMotionListener, { string = String.valueOf(av.getColumnSelection() .adjustForHiddenColumns(i)); - if ((i - startx - 1) * av.charWidth > maxX) + if ((i - startx - 1) * avCharWidth > maxX) { - gg.drawString(string, (i - startx - 1) * av.charWidth, y); - maxX = (i - startx + 1) * av.charWidth + fm.stringWidth(string); + gg.drawString(string, (i - startx - 1) * avCharWidth, y); + maxX = (i - startx + 1) * avCharWidth + fm.stringWidth(string); } - gg.drawLine( - ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), + gg.drawLine(((i - startx - 1) * avCharWidth) + (avCharWidth / 2), y + 2, - ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), + ((i - startx - 1) * avCharWidth) + (avCharWidth / 2), y + (fm.getDescent() * 2)); - } else { - gg.drawLine( - ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), - y + fm.getDescent(), - ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), - y + (fm.getDescent() * 2)); + gg.drawLine(((i - startx - 1) * avCharWidth) + (avCharWidth / 2), + y + fm.getDescent(), ((i - startx - 1) * avCharWidth) + + (avCharWidth / 2), y + (fm.getDescent() * 2)); } } @@ -515,10 +513,10 @@ public class ScalePanel extends JPanel implements MouseMotionListener, } gg.fillPolygon(new int[] - { res * av.charWidth - av.charHeight / 4, - res * av.charWidth + av.charHeight / 4, res * av.charWidth }, + { res * avCharWidth - avCharHeight / 4, + res * avCharWidth + avCharHeight / 4, res * avCharWidth }, new int[] - { y - av.charHeight / 2, y - av.charHeight / 2, y + 8 }, + { y - avCharHeight / 2, y - avCharHeight / 2, y + 8 }, 3); } @@ -527,7 +525,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener, if (reveal != null && reveal[0] > startx && reveal[0] < endx) { gg.drawString(MessageManager.getString("label.reveal_columns"), - reveal[0] * av.charWidth, 0); + reveal[0] * avCharWidth, 0); } } diff --git a/src/jalview/gui/SeqCanvas.java b/src/jalview/gui/SeqCanvas.java index ff576ec..4c04ad3 100755 --- a/src/jalview/gui/SeqCanvas.java +++ b/src/jalview/gui/SeqCanvas.java @@ -81,6 +81,7 @@ public class SeqCanvas extends JComponent public SeqCanvas(AlignmentPanel ap) { this.av = ap.av; + updateViewport(); fr = new FeatureRenderer(ap); sr = new SequenceRenderer(av); setLayout(new BorderLayout()); @@ -98,6 +99,13 @@ public class SeqCanvas extends JComponent return fr; } + int charHeight = 0, charWidth = 0; + + private void updateViewport() + { + charHeight = av.getCharHeight(); + charWidth = av.getCharWidth(); + } /** * DOCUMENT ME! * @@ -110,12 +118,12 @@ public class SeqCanvas extends JComponent * @param ypos * DOCUMENT ME! */ - void drawNorthScale(Graphics g, int startx, int endx, int ypos) + private void drawNorthScale(Graphics g, int startx, int endx, int ypos) { + updateViewport(); int scalestartx = startx - (startx % 10) + 10; g.setColor(Color.black); - // NORTH SCALE for (int i = scalestartx; i < endx; i += 10) { @@ -125,12 +133,12 @@ public class SeqCanvas extends JComponent value = av.getColumnSelection().adjustForHiddenColumns(value); } - g.drawString(String.valueOf(value), (i - startx - 1) * av.charWidth, - ypos - (av.charHeight / 2)); + g.drawString(String.valueOf(value), (i - startx - 1) * charWidth, + ypos - (charHeight / 2)); - g.drawLine(((i - startx - 1) * av.charWidth) + (av.charWidth / 2), - (ypos + 2) - (av.charHeight / 2), - ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), + g.drawLine(((i - startx - 1) * charWidth) + (charWidth / 2), + (ypos + 2) - (charHeight / 2), ((i - startx - 1) * charWidth) + + (charWidth / 2), ypos - 2); } } @@ -150,7 +158,7 @@ public class SeqCanvas extends JComponent void drawWestScale(Graphics g, int startx, int endx, int ypos) { FontMetrics fm = getFontMetrics(av.getFont()); - ypos += av.charHeight; + ypos += charHeight; if (av.hasHiddenColumns()) { @@ -188,9 +196,9 @@ public class SeqCanvas extends JComponent if (value != -1) { int x = LABEL_WEST - fm.stringWidth(String.valueOf(value)) - - av.charWidth / 2; - g.drawString(value + "", x, (ypos + (i * av.charHeight)) - - (av.charHeight / 5)); + - charWidth / 2; + g.drawString(value + "", x, (ypos + (i * charHeight)) + - (charHeight / 5)); } } } @@ -209,7 +217,7 @@ public class SeqCanvas extends JComponent */ void drawEastScale(Graphics g, int startx, int endx, int ypos) { - ypos += av.charHeight; + ypos += charHeight; if (av.hasHiddenColumns()) { @@ -240,8 +248,8 @@ public class SeqCanvas extends JComponent if (value != -1) { - g.drawString(String.valueOf(value), 0, (ypos + (i * av.charHeight)) - - (av.charHeight / 5)); + g.drawString(String.valueOf(value), 0, (ypos + (i * charHeight)) + - (charHeight / 5)); } } } @@ -265,10 +273,9 @@ public class SeqCanvas extends JComponent } fastpainting = true; fastPaint = true; - - gg.copyArea(horizontal * av.charWidth, vertical * av.charHeight, - imgWidth, imgHeight, -horizontal * av.charWidth, -vertical - * av.charHeight); + updateViewport(); + gg.copyArea(horizontal * charWidth, vertical * charHeight, imgWidth, + imgHeight, -horizontal * charWidth, -vertical * charHeight); int sr = av.startRes; int er = av.endRes; @@ -280,7 +287,7 @@ public class SeqCanvas extends JComponent if (horizontal > 0) // scrollbar pulled right, image to the left { er++; - transX = (er - sr - horizontal) * av.charWidth; + transX = (er - sr - horizontal) * charWidth; sr = er - horizontal; } else if (horizontal < 0) @@ -297,7 +304,7 @@ public class SeqCanvas extends JComponent } else { - transY = imgHeight - (vertical * av.charHeight); + transY = imgHeight - (vertical * charHeight); } } else if (vertical < 0) @@ -330,6 +337,7 @@ public class SeqCanvas extends JComponent // Set this to false to force a full panel paint public void paintComponent(Graphics g) { + updateViewport(); BufferedImage lcimg = img; // take reference since other threads may null // img and call later. super.paintComponent(g); @@ -348,8 +356,8 @@ public class SeqCanvas extends JComponent imgWidth = getWidth(); imgHeight = getHeight(); - imgWidth -= (imgWidth % av.charWidth); - imgHeight -= (imgHeight % av.charHeight); + imgWidth -= (imgWidth % charWidth); + imgHeight -= (imgHeight % charHeight); if ((imgWidth < 1) || (imgHeight < 1)) { @@ -412,17 +420,17 @@ public class SeqCanvas extends JComponent LABEL_EAST = 0; LABEL_WEST = 0; - if (av.scaleRightWrapped) + if (av.getScaleRightWrapped()) { LABEL_EAST = fm.stringWidth(getMask()); } - if (av.scaleLeftWrapped) + if (av.getScaleLeftWrapped()) { LABEL_WEST = fm.stringWidth(getMask()); } - return (cwidth - LABEL_EAST - LABEL_WEST) / av.charWidth; + return (cwidth - LABEL_EAST - LABEL_WEST) / charWidth; } /** @@ -466,28 +474,29 @@ public class SeqCanvas extends JComponent public void drawWrappedPanel(Graphics g, int canvasWidth, int canvasHeight, int startRes) { + updateViewport(); AlignmentI al = av.getAlignment(); FontMetrics fm = getFontMetrics(av.getFont()); - if (av.scaleRightWrapped) + if (av.getScaleRightWrapped()) { LABEL_EAST = fm.stringWidth(getMask()); } - if (av.scaleLeftWrapped) + if (av.getScaleLeftWrapped()) { LABEL_WEST = fm.stringWidth(getMask()); } - int hgap = av.charHeight; - if (av.scaleAboveWrapped) + int hgap = charHeight; + if (av.getScaleAboveWrapped()) { - hgap += av.charHeight; + hgap += charHeight; } - int cWidth = (canvasWidth - LABEL_EAST - LABEL_WEST) / av.charWidth; - int cHeight = av.getAlignment().getHeight() * av.charHeight; + int cWidth = (canvasWidth - LABEL_EAST - LABEL_WEST) / charWidth; + int cHeight = av.getAlignment().getHeight() * charHeight; av.setWrappedWidth(cWidth); @@ -514,12 +523,12 @@ public class SeqCanvas extends JComponent g.setFont(av.getFont()); g.setColor(Color.black); - if (av.scaleLeftWrapped) + if (av.getScaleLeftWrapped()) { drawWestScale(g, startRes, endx, ypos); } - if (av.scaleRightWrapped) + if (av.getScaleRightWrapped()) { g.translate(canvasWidth - LABEL_EAST, 0); drawEastScale(g, startRes, endx, ypos); @@ -528,12 +537,12 @@ public class SeqCanvas extends JComponent g.translate(LABEL_WEST, 0); - if (av.scaleAboveWrapped) + if (av.getScaleAboveWrapped()) { drawNorthScale(g, startRes, endx, ypos); } - if (av.hasHiddenColumns() && av.showHiddenMarkers) + if (av.hasHiddenColumns() && av.getShowHiddenMarkers()) { g.setColor(Color.blue); int res; @@ -549,11 +558,11 @@ public class SeqCanvas extends JComponent } gg.fillPolygon(new int[] - { res * av.charWidth - av.charHeight / 4, - res * av.charWidth + av.charHeight / 4, res * av.charWidth }, + { res * charWidth - charHeight / 4, + res * charWidth + charHeight / 4, res * charWidth }, new int[] - { ypos - (av.charHeight / 2), ypos - (av.charHeight / 2), - ypos - (av.charHeight / 2) + 8 }, 3); + { ypos - (charHeight / 2), ypos - (charHeight / 2), + ypos - (charHeight / 2) + 8 }, 3); } } @@ -564,11 +573,11 @@ public class SeqCanvas extends JComponent if (clip == null) { - g.setClip(0, 0, cWidth * av.charWidth, canvasHeight); + g.setClip(0, 0, cWidth * charWidth, canvasHeight); } else { - g.setClip(0, (int) clip.getBounds().getY(), cWidth * av.charWidth, + g.setClip(0, (int) clip.getBounds().getY(), cWidth * charWidth, (int) clip.getBounds().getHeight()); } @@ -632,6 +641,7 @@ public class SeqCanvas extends JComponent int startSeq, int endSeq, int offset) { + updateViewport(); if (!av.hasHiddenColumns()) { draw(g1, startRes, endRes, startSeq, endSeq, offset); @@ -644,9 +654,8 @@ public class SeqCanvas extends JComponent int blockStart = startRes; int blockEnd = endRes; - for (int i = 0; regions != null && i < regions.size(); i++) + for (int[] region : regions) { - int[] region = regions.get(i); int hideStart = region[0]; int hideEnd = region[1]; @@ -658,7 +667,7 @@ public class SeqCanvas extends JComponent blockEnd = hideStart - 1; - g1.translate(screenY * av.charWidth, 0); + g1.translate(screenY * charWidth, 0); draw(g1, blockStart, blockEnd, startSeq, endSeq, offset); @@ -666,12 +675,12 @@ public class SeqCanvas extends JComponent { g1.setColor(Color.blue); - g1.drawLine((blockEnd - blockStart + 1) * av.charWidth - 1, - 0 + offset, (blockEnd - blockStart + 1) * av.charWidth - - 1, (endSeq - startSeq) * av.charHeight + offset); + g1.drawLine((blockEnd - blockStart + 1) * charWidth - 1, + 0 + offset, (blockEnd - blockStart + 1) * charWidth - 1, + (endSeq - startSeq) * charHeight + offset); } - g1.translate(-screenY * av.charWidth, 0); + g1.translate(-screenY * charWidth, 0); screenY += blockEnd - blockStart + 1; blockStart = hideEnd + 1; } @@ -679,10 +688,10 @@ public class SeqCanvas extends JComponent if (screenY <= (endRes - startRes)) { blockEnd = blockStart + (endRes - startRes) - screenY; - g1.translate(screenY * av.charWidth, 0); + g1.translate(screenY * charWidth, 0); draw(g1, blockStart, blockEnd, startSeq, endSeq, offset); - g1.translate(-screenY * av.charWidth, 0); + g1.translate(-screenY * charWidth, 0); } } @@ -690,11 +699,12 @@ public class SeqCanvas extends JComponent // int startRes, int endRes, int startSeq, int endSeq, int x, int y, // int x1, int x2, int y1, int y2, int startx, int starty, - void draw(Graphics g, int startRes, int endRes, int startSeq, int endSeq, + private void draw(Graphics g, int startRes, int endRes, int startSeq, + int endSeq, int offset) { g.setFont(av.getFont()); - sr.prepare(g, av.renderGaps); + sr.prepare(g, av.isRenderGaps()); SequenceI nextSeq; @@ -710,12 +720,12 @@ public class SeqCanvas extends JComponent continue; } sr.drawSequence(nextSeq, av.getAlignment().findAllGroups(nextSeq), - startRes, endRes, offset + ((i - startSeq) * av.charHeight)); + startRes, endRes, offset + ((i - startSeq) * charHeight)); if (av.isShowSequenceFeatures()) { fr.drawSequence(g, nextSeq, startRes, endRes, offset - + ((i - startSeq) * av.charHeight)); + + ((i - startSeq) * charHeight)); } // / Highlight search Results once all sequences have been drawn @@ -730,8 +740,8 @@ public class SeqCanvas extends JComponent { sr.drawHighlightedText(nextSeq, visibleResults[r], visibleResults[r + 1], (visibleResults[r] - startRes) - * av.charWidth, offset - + ((i - startSeq) * av.charHeight)); + * charWidth, offset + + ((i - startSeq) * charHeight)); } } } @@ -739,9 +749,8 @@ public class SeqCanvas extends JComponent if (av.cursorMode && cursorY == i && cursorX >= startRes && cursorX <= endRes) { - sr.drawCursor(nextSeq, cursorX, - (cursorX - startRes) * av.charWidth, offset - + ((i - startSeq) * av.charHeight)); + sr.drawCursor(nextSeq, cursorX, (cursorX - startRes) * charWidth, + offset + ((i - startSeq) * charHeight)); } } @@ -767,7 +776,7 @@ public class SeqCanvas extends JComponent int sy = -1; int ex = -1; int groupIndex = -1; - int visWidth = (endRes - startRes + 1) * av.charWidth; + int visWidth = (endRes - startRes + 1) * charWidth; if ((group == null) && (av.getAlignment().getGroups().size() > 0)) { @@ -787,16 +796,16 @@ public class SeqCanvas extends JComponent for (i = startSeq; i < endSeq; i++) { - sx = (group.getStartRes() - startRes) * av.charWidth; - sy = offset + ((i - startSeq) * av.charHeight); - ex = (((group.getEndRes() + 1) - group.getStartRes()) * av.charWidth) - 1; + sx = (group.getStartRes() - startRes) * charWidth; + sy = offset + ((i - startSeq) * charHeight); + ex = (((group.getEndRes() + 1) - group.getStartRes()) * charWidth) - 1; if (sx + ex < 0 || sx > visWidth) { continue; } - if ((sx <= (endRes - startRes) * av.charWidth) + if ((sx <= (endRes - startRes) * charWidth) && group.getSequences(null).contains( av.getAlignment().getSequenceAt(i))) { @@ -804,7 +813,7 @@ public class SeqCanvas extends JComponent && !group.getSequences(null).contains( av.getAlignment().getSequenceAt(i + 1))) { - bottom = sy + av.charHeight; + bottom = sy + charHeight; } if (!inGroup) @@ -858,9 +867,9 @@ public class SeqCanvas extends JComponent ex = visWidth; } - else if (sx + ex >= (endRes - startRes + 1) * av.charWidth) + else if (sx + ex >= (endRes - startRes + 1) * charWidth) { - ex = (endRes - startRes + 1) * av.charWidth; + ex = (endRes - startRes + 1) * charWidth; } if (top != -1) @@ -882,7 +891,7 @@ public class SeqCanvas extends JComponent if (inGroup) { - sy = offset + ((i - startSeq) * av.charHeight); + sy = offset + ((i - startSeq) * charHeight); if (sx >= 0 && sx < visWidth) { g.drawLine(sx, oldY, sx, sy); @@ -903,9 +912,9 @@ public class SeqCanvas extends JComponent { ex = visWidth; } - else if (sx + ex >= (endRes - startRes + 1) * av.charWidth) + else if (sx + ex >= (endRes - startRes + 1) * charWidth) { - ex = (endRes - startRes + 1) * av.charWidth; + ex = (endRes - startRes + 1) * charWidth; } if (top != -1) diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index 1cc8715..afd3242 100644 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -20,10 +20,13 @@ */ package jalview.gui; +import jalview.api.AlignViewportI; import jalview.commands.EditCommand; import jalview.commands.EditCommand.Action; +import jalview.commands.EditCommand.Edit; import jalview.datamodel.ColumnSelection; import jalview.datamodel.SearchResults; +import jalview.datamodel.SearchResults.Match; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; @@ -34,7 +37,11 @@ import jalview.structure.SelectionListener; import jalview.structure.SelectionSource; import jalview.structure.SequenceListener; import jalview.structure.StructureSelectionManager; +import jalview.structure.VamsasSource; +import jalview.util.Comparison; +import jalview.util.MappingUtils; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.awt.BorderLayout; import java.awt.Color; @@ -165,16 +172,17 @@ public class SeqPanel extends JPanel implements MouseListener, int res = 0; int x = evt.getX(); - if (av.wrapAlignment) + if (av.getWrapAlignment()) { - int hgap = av.charHeight; - if (av.scaleAboveWrapped) + int hgap = av.getCharHeight(); + if (av.getScaleAboveWrapped()) { - hgap += av.charHeight; + hgap += av.getCharHeight(); } - int cHeight = av.getAlignment().getHeight() * av.charHeight + hgap + int cHeight = av.getAlignment().getHeight() * av.getCharHeight() + + hgap + seqCanvas.getAnnotationHeight(); int y = evt.getY(); @@ -218,15 +226,16 @@ public class SeqPanel extends JPanel implements MouseListener, int seq = 0; int y = evt.getY(); - if (av.wrapAlignment) + if (av.getWrapAlignment()) { - int hgap = av.charHeight; - if (av.scaleAboveWrapped) + int hgap = av.getCharHeight(); + if (av.getScaleAboveWrapped()) { - hgap += av.charHeight; + hgap += av.getCharHeight(); } - int cHeight = av.getAlignment().getHeight() * av.charHeight + hgap + int cHeight = av.getAlignment().getHeight() * av.getCharHeight() + + hgap + seqCanvas.getAnnotationHeight(); y -= hgap; @@ -243,22 +252,33 @@ public class SeqPanel extends JPanel implements MouseListener, return seq; } + /** + * When all of a sequence of edits are complete, put the resulting edit list + * on the history stack (undo list), and reset flags for editing in progress. + */ void endEditing() { - if (editCommand != null && editCommand.getSize() > 0) + try + { + if (editCommand != null && editCommand.getSize() > 0) + { + ap.alignFrame.addHistoryItem(editCommand); + av.firePropertyChange("alignment", null, av.getAlignment() + .getSequences()); + } + } finally { - ap.alignFrame.addHistoryItem(editCommand); - av.firePropertyChange("alignment", null, av.getAlignment() - .getSequences()); + /* + * Tidy up come what may... + */ + startseq = -1; + lastres = -1; + editingSeqs = false; + groupEditing = false; + keyboardNo1 = null; + keyboardNo2 = null; + editCommand = null; } - - startseq = -1; - lastres = -1; - editingSeqs = false; - groupEditing = false; - keyboardNo1 = null; - keyboardNo2 = null; - editCommand = null; } void setCursorRow() @@ -342,7 +362,7 @@ public class SeqPanel extends JPanel implements MouseListener, } endEditing(); - if (av.wrapAlignment) + if (av.getWrapAlignment()) { ap.scrollToWrappedVisible(seqCanvas.cursorX); } @@ -356,7 +376,7 @@ public class SeqPanel extends JPanel implements MouseListener, { ap.scrollUp(false); } - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { while (seqCanvas.cursorX < av.getColumnSelection() .adjustForHiddenColumns(av.startRes)) @@ -634,10 +654,16 @@ public class SeqPanel extends JPanel implements MouseListener, seqCanvas.revalidate(); } } + setStatusMessage(results); seqCanvas.highlightSearchResults(results); } @Override + public VamsasSource getVamsasSource() + { + return this.ap == null ? null : this.ap.av; + } + @Override public void updateColours(SequenceI seq, int index) { System.out.println("update the seqPanel colours"); @@ -774,42 +800,72 @@ public class SeqPanel extends JPanel implements MouseListener, */ int setStatusMessage(SequenceI sequence, int res, int seq) { - int pos = -1; - StringBuffer text = new StringBuffer("Sequence " + (seq + 1) + " ID: " - + sequence.getName()); + StringBuilder text = new StringBuilder(32); - Object obj = null; + /* + * Sequence number (if known), and sequence name. + */ + String seqno = seq == -1 ? "" : " " + (seq + 1); + text.append("Sequence" + seqno + " ID: " + sequence.getName()); + + String residue = null; + /* + * Try to translate the display character to residue name (null for gap). + */ + final String displayChar = String.valueOf(sequence.getCharAt(res)); if (av.getAlignment().isNucleotide()) { - obj = ResidueProperties.nucleotideName.get(sequence.getCharAt(res) - + ""); - if (obj != null) + residue = ResidueProperties.nucleotideName.get(displayChar); + if (residue != null) { - text.append(" Nucleotide: "); + text.append(" Nucleotide: ").append(residue); } } else { - obj = ResidueProperties.aa2Triplet.get(sequence.getCharAt(res) + ""); - if (obj != null) + residue = "X".equalsIgnoreCase(displayChar) ? "X" + : ResidueProperties.aa2Triplet.get(displayChar); + if (residue != null) { - text.append(" Residue: "); + text.append(" Residue: ").append(residue); } } - if (obj != null) + int pos = -1; + if (residue != null) { pos = sequence.findPosition(res); - if (obj != "") - { - text.append(obj + " (" + pos + ")"); - } + text.append(" (").append(Integer.toString(pos)).append(")"); } ap.alignFrame.statusBar.setText(text.toString()); return pos; } /** + * Set the status bar message to highlight the first matched position in + * search results. + * + * @param results + */ + private void setStatusMessage(SearchResults results) + { + List matches = results.getResults(); + if (!matches.isEmpty()) + { + Match m = matches.get(0); + SequenceI seq = m.getSequence(); + int sequenceIndex = this.av.getAlignment().findIndex(seq); + + /* + * Convert position in sequence (base 1) to sequence character array index + * (base 0) + */ + int start = m.getStart() - 1; + setStatusMessage(seq, start, sequenceIndex); + } + } + + /** * DOCUMENT ME! * * @param evt @@ -820,7 +876,7 @@ public class SeqPanel extends JPanel implements MouseListener, { if (mouseWheelPressed) { - int oldWidth = av.charWidth; + int oldWidth = av.getCharWidth(); // Which is bigger, left-right or up-down? if (Math.abs(evt.getY() - lastMousePress.getY()) > Math.abs(evt @@ -842,26 +898,28 @@ public class SeqPanel extends JPanel implements MouseListener, fontSize = 1; } - av.setFont(new Font(av.font.getName(), av.font.getStyle(), fontSize)); - av.charWidth = oldWidth; + av.setFont( + new Font(av.font.getName(), av.font.getStyle(), fontSize), + true); + av.setCharWidth(oldWidth); ap.fontChanged(); } else { - if (evt.getX() < lastMousePress.getX() && av.charWidth > 1) + if (evt.getX() < lastMousePress.getX() && av.getCharWidth() > 1) { - av.charWidth--; + av.setCharWidth(av.getCharWidth() - 1); } else if (evt.getX() > lastMousePress.getX()) { - av.charWidth++; + av.setCharWidth(av.getCharWidth() + 1); } ap.paintAlignment(false); } FontMetrics fm = getFontMetrics(av.getFont()); - av.validCharWidth = fm.charWidth('M') <= av.charWidth; + av.validCharWidth = fm.charWidth('M') <= av.getCharWidth(); lastMousePress = evt.getPoint(); @@ -924,7 +982,7 @@ public class SeqPanel extends JPanel implements MouseListener, } } - StringBuffer message = new StringBuffer(); + StringBuilder message = new StringBuilder(64); if (groupEditing) { message.append("Edit group:"); @@ -1149,8 +1207,8 @@ public class SeqPanel extends JPanel implements MouseListener, } else { - editCommand.appendEdit(Action.INSERT_GAP, groupSeqs, - startres, startres - lastres, av.getAlignment(), true); + appendEdit(Action.INSERT_GAP, groupSeqs, startres, startres + - lastres); } } else @@ -1165,8 +1223,8 @@ public class SeqPanel extends JPanel implements MouseListener, } else { - editCommand.appendEdit(Action.DELETE_GAP, groupSeqs, - startres, lastres - startres, av.getAlignment(), true); + appendEdit(Action.DELETE_GAP, groupSeqs, startres, lastres + - startres); } } @@ -1187,8 +1245,8 @@ public class SeqPanel extends JPanel implements MouseListener, } else { - editCommand.appendEdit(Action.INSERT_GAP, new SequenceI[] - { seq }, lastres, startres - lastres, av.getAlignment(), true); + appendEdit(Action.INSERT_GAP, new SequenceI[] + { seq }, lastres, startres - lastres); } } else @@ -1200,7 +1258,7 @@ public class SeqPanel extends JPanel implements MouseListener, { for (int j = lastres; j > startres; j--) { - if (!jalview.util.Comparison.isGap(seq.getCharAt(startres))) + if (!Comparison.isGap(seq.getCharAt(startres))) { endEditing(); break; @@ -1215,7 +1273,7 @@ public class SeqPanel extends JPanel implements MouseListener, int max = 0; for (int m = startres; m < lastres; m++) { - if (!jalview.util.Comparison.isGap(seq.getCharAt(m))) + if (!Comparison.isGap(seq.getCharAt(m))) { break; } @@ -1224,9 +1282,8 @@ public class SeqPanel extends JPanel implements MouseListener, if (max > 0) { - editCommand.appendEdit(Action.DELETE_GAP, - new SequenceI[] - { seq }, startres, max, av.getAlignment(), true); + appendEdit(Action.DELETE_GAP, new SequenceI[] + { seq }, startres, max); } } } @@ -1242,8 +1299,8 @@ public class SeqPanel extends JPanel implements MouseListener, } else { - editCommand.appendEdit(Action.INSERT_NUC, new SequenceI[] - { seq }, lastres, startres - lastres, av.getAlignment(), true); + appendEdit(Action.INSERT_NUC, new SequenceI[] + { seq }, lastres, startres - lastres); } } } @@ -1278,22 +1335,37 @@ public class SeqPanel extends JPanel implements MouseListener, } } - editCommand.appendEdit(Action.DELETE_GAP, seq, blankColumn, 1, - av.getAlignment(), true); + appendEdit(Action.DELETE_GAP, seq, blankColumn, 1); - editCommand.appendEdit(Action.INSERT_GAP, seq, j, 1, - av.getAlignment(), true); + appendEdit(Action.INSERT_GAP, seq, j, 1); } + /** + * Helper method to add and perform one edit action. + * + * @param action + * @param seq + * @param pos + * @param count + */ + protected void appendEdit(Action action, SequenceI[] seq, int pos, + int count) + { + + final Edit edit = new EditCommand().new Edit(action, seq, pos, count, + av.getAlignment().getGapCharacter()); + + editCommand.appendEdit(edit, av.getAlignment(), + true, null); + } + void deleteChar(int j, SequenceI[] seq, int fixedColumn) { - editCommand.appendEdit(Action.DELETE_GAP, seq, j, 1, - av.getAlignment(), true); + appendEdit(Action.DELETE_GAP, seq, j, 1); - editCommand.appendEdit(Action.INSERT_GAP, seq, fixedColumn, 1, - av.getAlignment(), true); + appendEdit(Action.INSERT_GAP, seq, fixedColumn, 1); } /** @@ -1416,7 +1488,7 @@ public class SeqPanel extends JPanel implements MouseListener, startWrapBlock = wrappedBlock; - if (av.wrapAlignment && seq > av.getAlignment().getHeight()) + if (av.getWrapAlignment() && seq > av.getAlignment().getHeight()) { JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager .getString("label.cannot_edit_annotations_in_wrapped_view"), @@ -1799,52 +1871,68 @@ public class SeqPanel extends JPanel implements MouseListener, // handles selection messages... // TODO: extend config options to allow user to control if selections may be // shared between viewports. - if (av == source - || !av.followSelection - || (av.isSelectionGroupChanged(false) || av - .isColSelChanged(false)) - || (source instanceof AlignViewport && ((AlignViewport) source) - .getSequenceSetId().equals(av.getSequenceSetId()))) + boolean iSentTheSelection = (av == source + || (source instanceof AlignViewport && ((AlignmentViewport) source) + .getSequenceSetId().equals(av.getSequenceSetId()))); + if (iSentTheSelection || !av.followSelection) + { + return; + } + + /* + * Ignore the selection if there is one of our own pending. + */ + if (av.isSelectionGroupChanged(false) || av.isColSelChanged(false)) + { + return; + } + + /* + * Check for selection in a view of which this one is a dna/protein + * complement. + */ + if (selectionFromTranslation(seqsel, colsel, source)) { return; } + // do we want to thread this ? (contention with seqsel and colsel locks, I // suspect) // rules are: colsel is copied if there is a real intersection between // sequence selection - boolean repaint = false, copycolsel = true; - // if (!av.isSelectionGroupChanged(false)) + boolean repaint = false; + boolean copycolsel = true; + + SequenceGroup sgroup = null; + if (seqsel != null && seqsel.getSize() > 0) { - SequenceGroup sgroup = null; - if (seqsel != null && seqsel.getSize() > 0) - { - if (av.getAlignment() == null) - { - jalview.bin.Cache.log.warn("alignviewport av SeqSetId=" - + av.getSequenceSetId() + " ViewId=" + av.getViewId() - + " 's alignment is NULL! returning immediatly."); - return; - } - sgroup = seqsel.intersect(av.getAlignment(), - (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null); - if ((sgroup == null || sgroup.getSize() == 0) - || (colsel == null || colsel.size() == 0)) - { - // don't copy columns if the region didn't intersect. - copycolsel = false; - } - } - if (sgroup != null && sgroup.getSize() > 0) + if (av.getAlignment() == null) { - av.setSelectionGroup(sgroup); + jalview.bin.Cache.log.warn("alignviewport av SeqSetId=" + + av.getSequenceSetId() + " ViewId=" + av.getViewId() + + " 's alignment is NULL! returning immediately."); + return; } - else + sgroup = seqsel.intersect(av.getAlignment(), + (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null); + if ((sgroup == null || sgroup.getSize() == 0) + || (colsel == null || colsel.size() == 0)) { - av.setSelectionGroup(null); + // don't copy columns if the region didn't intersect. + copycolsel = false; } - av.isSelectionGroupChanged(true); - repaint = true; } + if (sgroup != null && sgroup.getSize() > 0) + { + av.setSelectionGroup(sgroup); + } + else + { + av.setSelectionGroup(null); + } + av.isSelectionGroupChanged(true); + repaint = true; + if (copycolsel) { // the current selection is unset or from a previous message @@ -1872,6 +1960,7 @@ public class SeqPanel extends JPanel implements MouseListener, av.isColSelChanged(true); repaint = true; } + if (copycolsel && av.hasHiddenColumns() && (av.getColumnSelection() == null || av.getColumnSelection() @@ -1879,11 +1968,52 @@ public class SeqPanel extends JPanel implements MouseListener, { System.err.println("Bad things"); } - if (repaint) + if (repaint) // always true! { // probably finessing with multiple redraws here PaintRefresher.Refresh(this, av.getSequenceSetId()); // ap.paintAlignment(false); } } + + /** + * If this panel is a cdna/protein translation view of the selection source, + * tries to map the source selection to a local one, and returns true. Else + * returns false. + * + * @param seqsel + * @param colsel + * @param source + */ + protected boolean selectionFromTranslation(SequenceGroup seqsel, + ColumnSelection colsel, SelectionSource source) + { + if (!(source instanceof AlignViewportI)) { + return false; + } + final AlignViewportI sourceAv = (AlignViewportI) source; + if (sourceAv.getCodingComplement() != av && av.getCodingComplement() != sourceAv) + { + return false; + } + + /* + * Map sequence selection + */ + SequenceGroup sg = MappingUtils.mapSequenceGroup(seqsel, sourceAv, av); + av.setSelectionGroup(sg); + av.isSelectionGroupChanged(true); + + /* + * Map column selection + */ + ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, sourceAv, + av); + av.setColumnSelection(cs); + av.isColSelChanged(true); + + PaintRefresher.Refresh(this, av.getSequenceSetId()); + + return true; + } } diff --git a/src/jalview/gui/SequenceFetcher.java b/src/jalview/gui/SequenceFetcher.java index af4aa67..6a0c712 100755 --- a/src/jalview/gui/SequenceFetcher.java +++ b/src/jalview/gui/SequenceFetcher.java @@ -20,28 +20,81 @@ */ package jalview.gui; -import java.util.*; -import java.util.List; - -import java.awt.*; -import java.awt.event.*; - -import javax.swing.*; -import javax.swing.tree.DefaultMutableTreeNode; - -import com.stevesoft.pat.Regex; - -import jalview.datamodel.*; -import jalview.io.*; +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.DBRefEntry; +import jalview.datamodel.DBRefSource; +import jalview.datamodel.SequenceFeature; +import jalview.datamodel.SequenceI; +import jalview.io.FormatAdapter; +import jalview.io.IdentifyFile; import jalview.util.DBRefUtils; import jalview.util.MessageManager; import jalview.ws.dbsources.das.api.DasSourceRegistryI; import jalview.ws.seqfetcher.DbSourceProxy; + import java.awt.BorderLayout; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JInternalFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.SwingConstants; +import javax.swing.tree.DefaultMutableTreeNode; + +import com.stevesoft.pat.Regex; public class SequenceFetcher extends JPanel implements Runnable { - // ASequenceFetcher sfetch; + JLabel dbeg = new JLabel(); + + JDatabaseTree database; + + JButton databaseButt; + + JLabel jLabel1 = new JLabel(); + + JCheckBox replacePunctuation = new JCheckBox(); + + JButton ok = new JButton(); + + JButton clear = new JButton(); + + JButton example = new JButton(); + + JButton close = new JButton(); + + JPanel jPanel1 = new JPanel(); + + JTextArea textArea = new JTextArea(); + + JScrollPane jScrollPane1 = new JScrollPane(); + + JPanel jPanel2 = new JPanel(); + + JPanel jPanel3 = new JPanel(); + + JPanel jPanel4 = new JPanel(); + + BorderLayout borderLayout1 = new BorderLayout(); + + BorderLayout borderLayout2 = new BorderLayout(); + + BorderLayout borderLayout3 = new BorderLayout(); + JInternalFrame frame; IProgressIndicator guiWindow; @@ -62,6 +115,7 @@ public class SequenceFetcher extends JPanel implements Runnable private static Thread initingThread = null; + int debounceTrap = 0; /** * Blocking method that initialises and returns the shared instance of the * SequenceFetcher client @@ -136,9 +190,10 @@ public class SequenceFetcher extends JPanel implements Runnable return sfetch; } + private IProgressIndicator progressIndicator; public SequenceFetcher(IProgressIndicator guiIndic) { - final IProgressIndicator guiWindow = guiIndic; + this.progressIndicator = guiIndic; final SequenceFetcher us = this; // launch initialiser thread Thread sf = new Thread(new Runnable() @@ -147,9 +202,9 @@ public class SequenceFetcher extends JPanel implements Runnable @Override public void run() { - if (getSequenceFetcherSingleton(guiWindow) != null) + if (getSequenceFetcherSingleton(progressIndicator) != null) { - us.initGui(guiWindow); + us.initGui(progressIndicator); } else { @@ -283,7 +338,9 @@ public class SequenceFetcher extends JPanel implements Runnable public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) + { ok_actionPerformed(); + } } }); jPanel3.setLayout(borderLayout1); @@ -298,37 +355,21 @@ public class SequenceFetcher extends JPanel implements Runnable databaseButt.setFont(JvSwingUtils.getLabelFont()); database.addActionListener(new ActionListener() { - @Override public void actionPerformed(ActionEvent e) { - try - { - databaseButt.setText(database.getSelectedItem() - + (database.getSelectedSources().size() > 1 ? " (and " - + database.getSelectedSources().size() - + " others)" : "")); - String eq = database.getExampleQueries(); - dbeg.setText(MessageManager.formatMessage( - "label.example_query_param", new String[] - { eq })); - boolean enablePunct = !(eq != null && eq.indexOf(",") > -1); - for (DbSourceProxy dbs : database.getSelectedSources()) - { - if (dbs instanceof jalview.ws.dbsources.das.datamodel.DasSequenceSource) - { - enablePunct = false; - break; - } - } - replacePunctuation.setEnabled(enablePunct); + debounceTrap++; + String currentSelection = database.getSelectedItem(); - } catch (Exception ex) + if (!currentSelection.equalsIgnoreCase("pdb")) { - dbeg.setText(""); - replacePunctuation.setEnabled(true); + otherSourceAction(); } - jPanel2.repaint(); + if (currentSelection.equalsIgnoreCase("pdb") && ((debounceTrap % 2) == 0)) + { + pdbSourceAction(); + } + } }); dbeg.setText(""); @@ -347,6 +388,44 @@ public class SequenceFetcher extends JPanel implements Runnable } + private void pdbSourceAction() + { + databaseButt.setText(database.getSelectedItem()); + new PDBSearchPanel(this); + frame.dispose(); + } + + private void otherSourceAction() + { + try + { + databaseButt.setText(database.getSelectedItem() + + (database.getSelectedSources().size() > 1 ? " (and " + + database.getSelectedSources().size() + " others)" + : "")); + String eq = database.getExampleQueries(); + dbeg.setText(MessageManager.formatMessage( + "label.example_query_param", new String[] + { eq })); + boolean enablePunct = !(eq != null && eq.indexOf(",") > -1); + for (DbSourceProxy dbs : database.getSelectedSources()) + { + if (dbs instanceof jalview.ws.dbsources.das.datamodel.DasSequenceSource) + { + enablePunct = false; + break; + } + } + replacePunctuation.setEnabled(enablePunct); + + } catch (Exception ex) + { + dbeg.setText(""); + replacePunctuation.setEnabled(true); + } + jPanel2.repaint(); + } + protected void example_actionPerformed() { DbSourceProxy db = null; @@ -365,41 +444,7 @@ public class SequenceFetcher extends JPanel implements Runnable jPanel3.repaint(); } - JLabel dbeg = new JLabel(); - - JDatabaseTree database; - - JButton databaseButt; - - JLabel jLabel1 = new JLabel(); - - JCheckBox replacePunctuation = new JCheckBox(); - - JButton ok = new JButton(); - - JButton clear = new JButton(); - - JButton example = new JButton(); - - JButton close = new JButton(); - - JPanel jPanel1 = new JPanel(); - - JTextArea textArea = new JTextArea(); - - JScrollPane jScrollPane1 = new JScrollPane(); - - JPanel jPanel2 = new JPanel(); - - JPanel jPanel3 = new JPanel(); - - JPanel jPanel4 = new JPanel(); - BorderLayout borderLayout1 = new BorderLayout(); - - BorderLayout borderLayout2 = new BorderLayout(); - - BorderLayout borderLayout3 = new BorderLayout(); public void close_actionPerformed(ActionEvent e) { @@ -772,6 +817,10 @@ public class SequenceFetcher extends JPanel implements Runnable if (al != null && al.getHeight() > 0) { + if (title == null) + { + title = getDefaultRetrievalTitle(); + } if (alignFrame == null) { AlignFrame af = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH, @@ -784,17 +833,13 @@ public class SequenceFetcher extends JPanel implements Runnable // Alignments? } - if (title == null) - { - title = getDefaultRetrievalTitle(); - } SequenceFeature[] sfs = null; List alsqs; synchronized (alsqs = al.getSequences()) { for (SequenceI sq : alsqs) { - if ((sfs = (sq).getDatasetSequence().getSequenceFeatures()) != null) + if ((sfs = sq.getSequenceFeatures()) != null) { if (sfs.length > 0) { @@ -821,21 +866,7 @@ public class SequenceFetcher extends JPanel implements Runnable } else { - for (int i = 0; i < al.getHeight(); i++) - { - alignFrame.viewport.getAlignment().addSequence( - al.getSequenceAt(i)); // this - // also - // creates - // dataset - // sequence - // entries - } - alignFrame.viewport.setEndSeq(alignFrame.viewport.getAlignment() - .getHeight()); - alignFrame.viewport.getAlignment().getWidth(); - alignFrame.viewport.firePropertyChange("alignment", null, - alignFrame.viewport.getAlignment().getSequences()); + alignFrame.viewport.addAlignment(al, title); } } return al; @@ -855,4 +886,14 @@ public class SequenceFetcher extends JPanel implements Runnable } }); } + + public IProgressIndicator getProgressIndicator() + { + return progressIndicator; + } + + public void setProgressIndicator(IProgressIndicator progressIndicator) + { + this.progressIndicator = progressIndicator; + } } diff --git a/src/jalview/gui/SequenceRenderer.java b/src/jalview/gui/SequenceRenderer.java index c6a3df2..70acb7b 100755 --- a/src/jalview/gui/SequenceRenderer.java +++ b/src/jalview/gui/SequenceRenderer.java @@ -21,7 +21,6 @@ package jalview.gui; import jalview.api.FeatureRenderer; -import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.schemes.ColourSchemeI; @@ -38,6 +37,8 @@ import java.awt.Graphics; */ public class SequenceRenderer implements jalview.api.SequenceRenderer { + final static int CHAR_TO_UPPER = 'A' - 'a'; + AlignViewport av; FontMetrics fm; @@ -81,7 +82,8 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer // If EPS graphics, stringWidth will be a double, not an int double dwidth = fm.getStringBounds("M", g).getWidth(); - monospacedFont = (dwidth == fm.getStringBounds("|", g).getWidth() && av.charWidth == dwidth); + monospacedFont = (dwidth == fm.getStringBounds("|", g).getWidth() && av + .getCharWidth() == dwidth); this.renderGaps = renderGaps; } @@ -222,7 +224,8 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer int length = seq.getLength(); int curStart = -1; - int curWidth = av.charWidth; + int curWidth = av.getCharWidth(), avWidth = av.getCharWidth(), avHeight = av + .getCharHeight(); Color tempColour = null; @@ -250,26 +253,25 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer { if (tempColour != null) { - graphics.fillRect(av.charWidth * (curStart - start), y1, - curWidth, av.charHeight); + graphics.fillRect(avWidth * (curStart - start), y1, curWidth, + avHeight); } graphics.setColor(resBoxColour); curStart = i; - curWidth = av.charWidth; + curWidth = avWidth; tempColour = resBoxColour; } else { - curWidth += av.charWidth; + curWidth += avWidth; } i++; } - graphics.fillRect(av.charWidth * (curStart - start), y1, curWidth, - av.charHeight); + graphics.fillRect(avWidth * (curStart - start), y1, curWidth, avHeight); } @@ -293,7 +295,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer */ public void drawText(SequenceI seq, int start, int end, int y1) { - y1 += av.charHeight - av.charHeight / 5; // height/5 replaces pady + y1 += av.getCharHeight() - av.getCharHeight() / 5; // height/5 replaces pady int charOffset = 0; char s; @@ -301,12 +303,12 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer { end = seq.getLength() - 1; } - graphics.setColor(av.textColour); + graphics.setColor(av.getTextColour()); - if (monospacedFont && av.showText && allGroups.length == 0 - && !av.getColourText() && av.thresholdTextColour == 0) + if (monospacedFont && av.getShowText() && allGroups.length == 0 + && !av.getColourText() && av.getThresholdTextColour() == 0) { - if (av.renderGaps) + if (av.isRenderGaps()) { graphics.drawString(seq.getSequenceAsString(start, end + 1), 0, y1); } @@ -323,7 +325,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer boolean getboxColour = false; for (int i = start; i <= end; i++) { - graphics.setColor(av.textColour); + graphics.setColor(av.getTextColour()); getboxColour = false; s = seq.getCharAt(i); if (!renderGaps && jalview.util.Comparison.isGap(s)) @@ -393,7 +395,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer } } - if (av.thresholdTextColour > 0) + if (av.getThresholdTextColour() > 0) { if (!getboxColour) { @@ -401,9 +403,9 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer } if (resBoxColour.getRed() + resBoxColour.getBlue() - + resBoxColour.getGreen() < av.thresholdTextColour) + + resBoxColour.getGreen() < av.getThresholdTextColour()) { - graphics.setColor(av.textColour2); + graphics.setColor(av.getTextColour2()); } } if (av.getShowUnconserved()) @@ -415,26 +417,39 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer } - charOffset = (av.charWidth - fm.charWidth(s)) / 2; - graphics.drawString(String.valueOf(s), charOffset + av.charWidth + charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2; + graphics.drawString(String.valueOf(s), + charOffset + av.getCharWidth() * (i - start), y1); } } } + /** + * Returns 'conservedChar' to represent the given position if the sequence + * character at that position is equal to the consensus (ignoring case), else + * returns the sequence character + * + * @param usesrep + * @param position + * @param sequenceChar + * @param conservedChar + * @return + */ private char getDisplayChar(final boolean usesrep, int position, - char s, char c) + char sequenceChar, char conservedChar) { - // TODO - use currentSequenceGroup rather than alignemnt + // TODO - use currentSequenceGroup rather than alignment // currentSequenceGroup.getConsensus() char conschar = (usesrep) ? av.getAlignment().getSeqrep().getCharAt(position) : av.getAlignmentConsensusAnnotation().annotations[position].displayCharacter .charAt(0); - if (conschar != '-' && s == conschar) + if (conschar != '-' + && (sequenceChar == conschar || sequenceChar + CHAR_TO_UPPER == conschar)) { - s = c; + sequenceChar = conservedChar; } - return s; + return sequenceChar; } /** @@ -487,17 +502,17 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer public void drawHighlightedText(SequenceI seq, int start, int end, int x1, int y1) { - int pady = av.charHeight / 5; + int pady = av.getCharHeight() / 5; int charOffset = 0; graphics.setColor(Color.BLACK); - graphics.fillRect(x1, y1, av.charWidth * (end - start + 1), - av.charHeight); + graphics.fillRect(x1, y1, av.getCharWidth() * (end - start + 1), + av.getCharHeight()); graphics.setColor(Color.white); char s = '~'; // Need to find the sequence position here. - if (av.validCharWidth) + if (av.isValidCharWidth()) { for (int i = start; i <= end; i++) { @@ -506,29 +521,30 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer s = seq.getCharAt(i); } - charOffset = (av.charWidth - fm.charWidth(s)) / 2; - graphics.drawString(String.valueOf(s), charOffset + x1 - + (av.charWidth * (i - start)), (y1 + av.charHeight) - pady); + charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2; + graphics.drawString(String.valueOf(s), + charOffset + x1 + (av.getCharWidth() * (i - start)), + (y1 + av.getCharHeight()) - pady); } } } public void drawCursor(SequenceI seq, int res, int x1, int y1) { - int pady = av.charHeight / 5; + int pady = av.getCharHeight() / 5; int charOffset = 0; graphics.setColor(Color.black); - graphics.fillRect(x1, y1, av.charWidth, av.charHeight); + graphics.fillRect(x1, y1, av.getCharWidth(), av.getCharHeight()); - if (av.validCharWidth) + if (av.isValidCharWidth()) { graphics.setColor(Color.white); char s = seq.getCharAt(res); - charOffset = (av.charWidth - fm.charWidth(s)) / 2; + charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2; graphics.drawString(String.valueOf(s), charOffset + x1, - (y1 + av.charHeight) - pady); + (y1 + av.getCharHeight()) - pady); } } diff --git a/src/jalview/gui/SliderPanel.java b/src/jalview/gui/SliderPanel.java index c842826..af6bfff 100755 --- a/src/jalview/gui/SliderPanel.java +++ b/src/jalview/gui/SliderPanel.java @@ -20,16 +20,20 @@ */ package jalview.gui; -import java.util.*; +import jalview.datamodel.SequenceGroup; +import jalview.jbgui.GSliderPanel; +import jalview.schemes.ColourSchemeI; +import jalview.util.MessageManager; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.event.*; +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Iterator; -import jalview.datamodel.*; -import jalview.jbgui.*; -import jalview.schemes.*; -import jalview.util.MessageManager; +import javax.swing.JInternalFrame; +import javax.swing.JLayeredPane; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; /** * DOCUMENT ME! @@ -286,13 +290,15 @@ public class SliderPanel extends GSliderPanel } else { - toChange.setThreshold(i, ap.av.getIgnoreGapsConsensus()); + toChange.setThreshold(i, ap.av.isIgnoreGapsConsensus()); } if (allGroups != null && allGroups.hasNext()) { while ((toChange = allGroups.next().cs) == null && allGroups.hasNext()) + { ; + } } else { diff --git a/src/jalview/gui/SplitFrame.java b/src/jalview/gui/SplitFrame.java new file mode 100644 index 0000000..5c4e4d2 --- /dev/null +++ b/src/jalview/gui/SplitFrame.java @@ -0,0 +1,639 @@ +package jalview.gui; + +import java.awt.Component; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.beans.PropertyVetoException; +import java.util.Map.Entry; + +import javax.swing.AbstractAction; +import javax.swing.InputMap; +import javax.swing.JComponent; +import javax.swing.JMenuItem; +import javax.swing.KeyStroke; +import javax.swing.event.InternalFrameAdapter; +import javax.swing.event.InternalFrameEvent; + +import jalview.api.SplitContainerI; +import jalview.api.ViewStyleI; +import jalview.datamodel.AlignmentI; +import jalview.jbgui.GAlignFrame; +import jalview.jbgui.GSplitFrame; +import jalview.structure.StructureSelectionManager; +import jalview.viewmodel.AlignmentViewport; + +/** + * An internal frame on the desktop that hosts a horizontally split view of + * linked DNA and Protein alignments. Additional views can be created in linked + * pairs, expanded to separate split frames, or regathered into a single frame. + *

+ * (Some) operations on each alignment are automatically mirrored on the other. + * These include mouseover (highlighting), sequence and column selection, + * sequence ordering and sorting, and grouping, colouring and sorting by tree. + * + * @author gmcarstairs + * + */ +public class SplitFrame extends GSplitFrame implements SplitContainerI +{ + private static final long serialVersionUID = 1L; + + public SplitFrame(GAlignFrame top, GAlignFrame bottom) + { + super(top, bottom); + init(); + } + + /** + * Initialise this frame. + */ + protected void init() + { + getTopFrame().setSplitFrame(this); + getBottomFrame().setSplitFrame(this); + getTopFrame().setVisible(true); + getBottomFrame().setVisible(true); + + ((AlignFrame) getTopFrame()).getViewport().setCodingComplement( + ((AlignFrame) getBottomFrame()).getViewport()); + + int width = ((AlignFrame) getTopFrame()).getWidth(); + // about 50 pixels for the SplitFrame's title bar etc + int height = ((AlignFrame) getTopFrame()).getHeight() + + ((AlignFrame) getBottomFrame()).getHeight() + 50; + height = Math.min(height, Desktop.instance.getHeight() - 20); + // setSize(AlignFrame.DEFAULT_WIDTH, Desktop.instance.getHeight() - 20); + setSize(width, height); + + adjustLayout(); + + addCloseFrameListener(); + + addKeyListener(); + + addKeyBindings(); + + addCommandListeners(); + } + + /** + * Set the top and bottom frames to listen to each others Commands (e.g. Edit, + * Order). + */ + protected void addCommandListeners() + { + // TODO if CommandListener is only ever 1:1 for complementary views, + // may change broadcast pattern to direct messaging (more efficient) + final StructureSelectionManager ssm = StructureSelectionManager + .getStructureSelectionManager(Desktop.instance); + ssm.addCommandListener(((AlignFrame) getTopFrame()).getViewport()); + ssm.addCommandListener(((AlignFrame) getBottomFrame()).getViewport()); + } + + /** + * Do any tweaking and twerking of the layout wanted. + */ + public void adjustLayout() + { + /* + * Ensure sequence ids are the same width for good alignment. + */ + int w1 = ((AlignFrame) getTopFrame()).getViewport().getIdWidth(); + int w2 = ((AlignFrame) getBottomFrame()).getViewport().getIdWidth(); + int w3 = Math.max(w1, w2); + if (w1 != w3) + { + ((AlignFrame) getTopFrame()).getViewport().setIdWidth(w3); + } + if (w2 != w3) + { + ((AlignFrame) getBottomFrame()).getViewport().setIdWidth(w3); + } + + /* + * Set the character width for protein to 3 times that for dna. + */ + boolean scaleThreeToOne = true; // TODO a new Preference option? + if (scaleThreeToOne) + { + final AlignViewport topViewport = ((AlignFrame) getTopFrame()).viewport; + final AlignViewport bottomViewport = ((AlignFrame) getBottomFrame()).viewport; + final AlignmentI topAlignment = topViewport.getAlignment(); + final AlignmentI bottomAlignment = bottomViewport.getAlignment(); + AlignmentViewport cdna = topAlignment.isNucleotide() ? topViewport + : (bottomAlignment.isNucleotide() ? bottomViewport : null); + AlignmentViewport protein = !topAlignment.isNucleotide() ? topViewport + : (!bottomAlignment.isNucleotide() ? bottomViewport : null); + if (protein != null && cdna != null) + { + ViewStyleI vs = cdna.getViewStyle(); + ViewStyleI vs2 = protein.getViewStyle(); + vs2.setCharWidth(3 * vs.getCharWidth()); + protein.setViewStyle(vs2); + } + } + } + + /** + * Add a listener to tidy up when the frame is closed. + */ + protected void addCloseFrameListener() + { + addInternalFrameListener(new InternalFrameAdapter() + { + @Override + public void internalFrameClosed(InternalFrameEvent evt) + { + if (getTopFrame() instanceof AlignFrame) + { + ((AlignFrame) getTopFrame()) + .closeMenuItem_actionPerformed(true); + } + if (getBottomFrame() instanceof AlignFrame) + { + ((AlignFrame) getBottomFrame()) + .closeMenuItem_actionPerformed(true); + } + }; + }); + } + + /** + * Add a key listener that delegates to whichever split component the mouse is + * in (or does nothing if neither). + */ + protected void addKeyListener() + { + addKeyListener(new KeyAdapter() { + + @Override + public void keyPressed(KeyEvent e) + { + AlignFrame af = (AlignFrame) getFrameAtMouse(); + + /* + * Intercept and override any keys here if wanted. + */ + if (!overrideKey(e, af)) + { + if (af != null) + { + for (KeyListener kl : af.getKeyListeners()) + { + kl.keyPressed(e); + } + } + } + } + + @Override + public void keyReleased(KeyEvent e) + { + Component c = getFrameAtMouse(); + if (c != null) + { + for (KeyListener kl : c.getKeyListeners()) + { + kl.keyReleased(e); + } + } + } + + }); + } + + /** + * Returns true if the key event is overriden and actioned (or ignored) here, + * else returns false, indicating it should be delegated to the AlignFrame's + * usual handler. + *

+ * We can't handle Cmd-Key combinations here, instead this is done by + * overriding key bindings. + * + * @see addKeyOverrides + * @param e + * @param af + * @return + */ + protected boolean overrideKey(KeyEvent e, AlignFrame af) + { + boolean actioned = false; + int keyCode = e.getKeyCode(); + switch (keyCode) + { + case KeyEvent.VK_DOWN: + if (e.isAltDown() || !af.viewport.cursorMode) + { + /* + * Key down (or Alt-key-down in cursor mode) - move selected sequences + */ + ((AlignFrame) getTopFrame()).moveSelectedSequences(false); + ((AlignFrame) getBottomFrame()).moveSelectedSequences(false); + actioned = true; + e.consume(); + } + break; + case KeyEvent.VK_UP: + if (e.isAltDown() || !af.viewport.cursorMode) + { + /* + * Key up (or Alt-key-up in cursor mode) - move selected sequences + */ + ((AlignFrame) getTopFrame()).moveSelectedSequences(true); + ((AlignFrame) getBottomFrame()).moveSelectedSequences(true); + actioned = true; + e.consume(); + } + default: + } + return actioned; + } + + /** + * Set key bindings (recommended for Swing over key accelerators). + */ + private void addKeyBindings() + { + overrideDelegatedKeyBindings(); + + overrideImplementedKeyBindings(); + } + + /** + * Override key bindings with alternative action methods implemented in this + * class. + */ + protected void overrideImplementedKeyBindings() + { + overrideFind(); + overrideNewView(); + overrideCloseView(); + overrideExpandViews(); + overrideGatherViews(); + } + + /** + * Replace Cmd-W close view action with our version. + */ + protected void overrideCloseView() + { + AbstractAction action; + /* + * Ctrl-W / Cmd-W - close view or window + */ + KeyStroke key_cmdW = KeyStroke.getKeyStroke(KeyEvent.VK_W, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + action = new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + closeView_actionPerformed(); + } + }; + overrideKeyBinding(key_cmdW, action); + } + + /** + * Replace Cmd-T new view action with our version. + */ + protected void overrideNewView() + { + /* + * Ctrl-T / Cmd-T open new view + */ + KeyStroke key_cmdT = KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + AbstractAction action = new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + newView_actionPerformed(); + } + }; + overrideKeyBinding(key_cmdT, action); + } + + /** + * For now, delegates key events to the corresponding key accelerator for the + * AlignFrame that the mouse is in. Hopefully can be simplified in future if + * AlignFrame is changed to use key bindings rather than accelerators. + */ + protected void overrideDelegatedKeyBindings() + { + if (getTopFrame() instanceof AlignFrame) + { + /* + * Get all accelerator keys in the top frame (the bottom should be + * identical) and override each one. + */ + for (Entry acc : ((AlignFrame) getTopFrame()) + .getAccelerators().entrySet()) + { + overrideKeyBinding(acc); + } + } + } + + /** + * Overrides an AlignFrame key accelerator with our version which delegates to + * the action listener in whichever frame has the mouse (and does nothing if + * neither has). + * + * @param acc + */ + private void overrideKeyBinding(Entry acc) + { + final KeyStroke ks = acc.getKey(); + InputMap inputMap = this.getInputMap(JComponent.WHEN_FOCUSED); + inputMap.put(ks, ks); + this.getActionMap().put(ks, new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + Component c = getFrameAtMouse(); + if (c != null && c instanceof AlignFrame) + { + for (ActionListener a : ((AlignFrame) c).getAccelerators() + .get(ks).getActionListeners()) + { + a.actionPerformed(null); + } + } + } + }); + } + + /** + * Replace an accelerator key's action with the specified action. + * + * @param ks + */ + protected void overrideKeyBinding(KeyStroke ks, AbstractAction action) + { + this.getActionMap().put(ks, action); + overrideMenuItem(ks, action); + } + + /** + * Create and link new views (with matching names) in both panes. + *

+ * Note this is _not_ multiple tabs, each hosting a split pane view, rather it + * is a single split pane with each split holding multiple tabs which are + * linked in pairs. + *

+ * TODO implement instead with a tabbed holder in the SplitView, each tab + * holding a single JSplitPane. Would avoid a duplicated tab, at the cost of + * some additional coding. + */ + protected void newView_actionPerformed() + { + AlignFrame topFrame = (AlignFrame) getTopFrame(); + AlignFrame bottomFrame = (AlignFrame) getBottomFrame(); + + AlignmentPanel newTopPanel = topFrame.newView(null, true); + AlignmentPanel newBottomPanel = bottomFrame.newView(null, true); + + /* + * This currently (for the first new view only) leaves the top pane on tab 0 + * but the bottom on tab 1. This results from 'setInitialTabVisible' echoing + * from the bottom back to the first frame. Next line is a fudge to work + * around this. TODO find a better way. + */ + if (topFrame.getTabIndex() != bottomFrame.getTabIndex()) + { + topFrame.setDisplayedView(newTopPanel); + } + + newBottomPanel.av.viewName = newTopPanel.av.viewName; + newTopPanel.av.setCodingComplement(newBottomPanel.av); + + final StructureSelectionManager ssm = StructureSelectionManager + .getStructureSelectionManager(Desktop.instance); + ssm.addCommandListener(newTopPanel.av); + ssm.addCommandListener(newBottomPanel.av); + } + + /** + * Close the currently selected view in both panes. If there is only one view, + * close this split frame. + */ + protected void closeView_actionPerformed() + { + int viewCount = ((AlignFrame) getTopFrame()).getAlignPanels().size(); + if (viewCount < 2) + { + close(); + return; + } + + AlignmentPanel topPanel = ((AlignFrame) getTopFrame()).alignPanel; + AlignmentPanel bottomPanel = ((AlignFrame) getBottomFrame()).alignPanel; + + ((AlignFrame) getTopFrame()).closeView(topPanel); + ((AlignFrame) getBottomFrame()).closeView(bottomPanel); + + } + + /** + * Close child frames and this split frame. + */ + public void close() + { + ((AlignFrame) getTopFrame()).closeMenuItem_actionPerformed(true); + ((AlignFrame) getBottomFrame()).closeMenuItem_actionPerformed(true); + try + { + this.setClosed(true); + } catch (PropertyVetoException e) + { + // ignore + } + } + + /** + * Replace AlignFrame 'expand views' action with SplitFrame version. + */ + protected void overrideExpandViews() + { + KeyStroke key_X = KeyStroke.getKeyStroke(KeyEvent.VK_X, 0, false); + AbstractAction action = new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + expandViews_actionPerformed(); + } + }; + overrideMenuItem(key_X, action); + } + + /** + * Replace AlignFrame 'gather views' action with SplitFrame version. + */ + protected void overrideGatherViews() + { + KeyStroke key_G = KeyStroke.getKeyStroke(KeyEvent.VK_G, 0, false); + AbstractAction action = new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + gatherViews_actionPerformed(); + } + }; + overrideMenuItem(key_G, action); + } + + /** + * Override the menu action associated with the keystroke in the child frames, + * replacing it with the given action. + * + * @param ks + * @param action + */ + private void overrideMenuItem(KeyStroke ks, AbstractAction action) + { + overrideMenuItem(ks, action, getTopFrame()); + overrideMenuItem(ks, action, getBottomFrame()); + } + + /** + * Override the menu action associated with the keystroke in one child frame, + * replacing it with the given action. Mwahahahaha. + * + * @param key + * @param action + * @param comp + */ + private void overrideMenuItem(KeyStroke key, final AbstractAction action, + JComponent comp) + { + if (comp instanceof AlignFrame) + { + JMenuItem mi = ((AlignFrame) comp).getAccelerators().get(key); + if (mi != null) + { + for (ActionListener al : mi.getActionListeners()) + { + mi.removeActionListener(al); + } + mi.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + action.actionPerformed(e); + } + }); + } + } + } + + /** + * Expand any multiple views (which are always in pairs) into separate split + * frames. + */ + protected void expandViews_actionPerformed() + { + Desktop.instance.explodeViews(this); + } + + /** + * Gather any other SplitFrame views of this alignment back in as multiple + * (pairs of) views in this SplitFrame. + */ + protected void gatherViews_actionPerformed() + { + Desktop.instance.gatherViews(this); + } + + /** + * Returns the alignment in the complementary frame to the one given. + */ + @Override + public AlignmentI getComplement(Object alignFrame) + { + if (alignFrame == this.getTopFrame()) + { + return ((AlignFrame) getBottomFrame()).viewport.getAlignment(); + } + else if (alignFrame == this.getBottomFrame()) + { + return ((AlignFrame) getTopFrame()).viewport.getAlignment(); + } + return null; + } + + /** + * Returns the title of the complementary frame to the one given. + */ + @Override + public String getComplementTitle(Object alignFrame) + { + if (alignFrame == this.getTopFrame()) + { + return ((AlignFrame) getBottomFrame()).getTitle(); + } + else if (alignFrame == this.getBottomFrame()) + { + return ((AlignFrame) getTopFrame()).getTitle(); + } + return null; + } + + /** + * Set the 'other half' to hidden / revealed. + */ + @Override + public void setComplementVisible(Object alignFrame, boolean show) + { + /* + * Hiding the AlignPanel suppresses unnecessary repaints + */ + if (alignFrame == getTopFrame()) + { + ((AlignFrame) getBottomFrame()).alignPanel.setVisible(show); + } + else if (alignFrame == getBottomFrame()) + { + ((AlignFrame) getTopFrame()).alignPanel.setVisible(show); + } + super.setComplementVisible(alignFrame, show); + } + + /** + * Replace Cmd-F Find action with our version. This is necessary because the + * 'default' Finder searches in the first AlignFrame it finds. We need it to + * search in the half of the SplitFrame that has the mouse. + */ + protected void overrideFind() + { + /* + * Ctrl-F / Cmd-F open Finder dialog, 'focused' on the right alignment + */ + KeyStroke key_cmdF = KeyStroke.getKeyStroke(KeyEvent.VK_F, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + AbstractAction action = new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + Component c = getFrameAtMouse(); + if (c != null && c instanceof AlignFrame) + { + AlignFrame af = (AlignFrame) c; + new Finder(af.viewport, af.alignPanel); + } + } + }; + overrideKeyBinding(key_cmdF, action); + } +} + diff --git a/src/jalview/gui/StructureChooser.java b/src/jalview/gui/StructureChooser.java new file mode 100644 index 0000000..3a54cc1 --- /dev/null +++ b/src/jalview/gui/StructureChooser.java @@ -0,0 +1,634 @@ +/* + + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2) + * Copyright (C) 2014 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 . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ + +package jalview.gui; + +import jalview.datamodel.DBRefEntry; +import jalview.datamodel.PDBEntry; +import jalview.datamodel.SequenceI; +import jalview.jbgui.GStructureChooser; +import jalview.jbgui.PDBDocFieldPreferences; +import jalview.util.MessageManager; +import jalview.ws.dbsources.PDBRestClient; +import jalview.ws.dbsources.PDBRestClient.PDBDocField; +import jalview.ws.uimodel.PDBRestRequest; +import jalview.ws.uimodel.PDBRestResponse; +import jalview.ws.uimodel.PDBRestResponse.PDBResponseSummary; + +import java.awt.event.ItemEvent; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Vector; + +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; + +/** + * Provides the behaviors for the Structure chooser Panel + * + * @author tcnofoegbu + * + */ +@SuppressWarnings("serial") +public class StructureChooser extends GStructureChooser +{ + private boolean structuresDiscovered = false; + + private SequenceI selectedSequence; + + private SequenceI[] selectedSequences; + + private IProgressIndicator progressIndicator; + + private Collection discoveredStructuresSet; + + private PDBRestRequest lastPdbRequest; + + private PDBRestClient pdbRestCleint; + + private String selectedPdbFileName; + + private boolean isValidPBDEntry; + + public StructureChooser(SequenceI[] selectedSeqs, SequenceI selectedSeq, + AlignmentPanel ap) + { + this.ap = ap; + this.selectedSequence = selectedSeq; + this.selectedSequences = selectedSeqs; + this.progressIndicator = (ap == null) ? null : ap.alignFrame; + init(); + } + + /** + * Initializes parameters used by the Structure Chooser Panel + */ + public void init() + { + Thread discoverPDBStructuresThread = new Thread(new Runnable() + { + @Override + public void run() + { + long startTime = System.currentTimeMillis(); + String msg = MessageManager.getString("status.fetching_db_refs"); + updateProgressIndicator(msg, startTime); + fetchStructuresMetaData(); + populateFilterComboBox(); + updateProgressIndicator(null, startTime); + mainFrame.setVisible(true); + updateCurrentView(); + } + }); + discoverPDBStructuresThread.start(); + } + + /** + * Updates the progress indicator with the specified message + * + * @param message + * displayed message for the operation + * @param id + * unique handle for this indicator + */ + public void updateProgressIndicator(String message, long id) + { + if (progressIndicator != null) + { + progressIndicator.setProgressBar(message, id); + } + } + + /** + * Retrieve meta-data for all the structure(s) for a given sequence(s) in a + * selection group + */ + public void fetchStructuresMetaData() + { + long startTime = System.currentTimeMillis(); + Collection wantedFields = PDBDocFieldPreferences + .getStructureSummaryFields(); + + discoveredStructuresSet = new LinkedHashSet(); + for (SequenceI seq : selectedSequences) + { + PDBRestRequest pdbRequest = new PDBRestRequest(); + pdbRequest.setAllowEmptySeq(false); + pdbRequest.setResponseSize(500); + pdbRequest.setFieldToSearchBy("(text:"); + pdbRequest.setWantedFields(wantedFields); + pdbRequest.setSearchTerm(buildQuery(seq) + ")"); + pdbRequest.setAssociatedSequence(seq.getName()); + pdbRestCleint = new PDBRestClient(); + PDBRestResponse resultList = pdbRestCleint.executeRequest(pdbRequest); + lastPdbRequest = pdbRequest; + if (resultList.getSearchSummary() != null + && !resultList.getSearchSummary().isEmpty()) + { + discoveredStructuresSet.addAll(resultList.getSearchSummary()); + updateSequenceDbRef(seq, resultList.getSearchSummary()); + } + } + + int noOfStructuresFound = 0; + if (discoveredStructuresSet != null + && !discoveredStructuresSet.isEmpty()) + { + tbl_summary.setModel(PDBRestResponse.getTableModel(lastPdbRequest, + discoveredStructuresSet)); + structuresDiscovered = true; + noOfStructuresFound = discoveredStructuresSet.size(); + } + String totalTime = (System.currentTimeMillis() - startTime) + + " milli secs"; + mainFrame.setTitle("Structure Chooser - " + noOfStructuresFound + + " Found (" + totalTime + ")"); + } + + /** + * Update the DBRef entry for a given sequence with values retrieved from + * PDBResponseSummary + * + * @param seq + * the Sequence to update its DBRef entry + * @param responseSummaries + * a collection of PDBResponseSummary + */ + public void updateSequenceDbRef(SequenceI seq, + Collection responseSummaries) + { + for (PDBResponseSummary response : responseSummaries) + { + PDBEntry newEntry = new PDBEntry(); + newEntry.setId(response.getPdbId()); + newEntry.setType("PDB"); + seq.getDatasetSequence().addPDBId(newEntry); + } + } + + /** + * Builds a query string for a given sequences using its DBRef entries + * + * @param seq + * the sequences to build a query for + * @return the built query string + */ + @SuppressWarnings("unchecked") + public static String buildQuery(SequenceI seq) + { + String query = seq.getName(); + StringBuilder queryBuilder = new StringBuilder(); + int count = 0; + + if (seq.getPDBId() != null) + { + for (PDBEntry entry : (Vector) seq.getPDBId()) + { + queryBuilder.append("text:").append(entry.getId()).append(" OR "); + } + } + + if (seq.getDBRef() != null && seq.getDBRef().length != 0) + { + for (DBRefEntry dbRef : seq.getDBRef()) + { + queryBuilder.append("text:") + .append(dbRef.getAccessionId().replaceAll("GO:", "")) + .append(" OR "); + ++count; + if (count > 10) + { + break; + } + } + int endIndex = queryBuilder.lastIndexOf(" OR "); + query = queryBuilder.toString().substring(5, endIndex); + } + return query; + } + + /** + * Filters a given list of discovered structures based on supplied argument + * + * @param fieldToFilterBy + * the field to filter by + */ + public void filterResultSet(final String fieldToFilterBy) + { + Thread filterThread = new Thread(new Runnable() + { + @Override + public void run() + { + long startTime = System.currentTimeMillis(); + try + { + lbl_loading.setVisible(true); + + Collection wantedFields = PDBDocFieldPreferences + .getStructureSummaryFields(); + Collection filteredResponse = new HashSet(); + for (SequenceI seq : selectedSequences) + { + PDBRestRequest pdbRequest = new PDBRestRequest(); + pdbRequest.setAllowEmptySeq(false); + pdbRequest.setResponseSize(1); + pdbRequest.setFieldToSearchBy("(text:"); + pdbRequest.setFieldToSortBy(fieldToFilterBy, + !chk_invertFilter.isSelected()); + pdbRequest.setSearchTerm(buildQuery(seq) + ")"); + pdbRequest.setWantedFields(wantedFields); + pdbRequest.setAssociatedSequence(seq.getName()); + pdbRestCleint = new PDBRestClient(); + PDBRestResponse resultList = pdbRestCleint + .executeRequest(pdbRequest); + lastPdbRequest = pdbRequest; + if (resultList.getSearchSummary() != null + && !resultList.getSearchSummary().isEmpty()) + { + filteredResponse.addAll(resultList.getSearchSummary()); + } + } + + if (!filteredResponse.isEmpty()) + { + final int filterResponseCount = filteredResponse.size(); + Collection reorderedStructuresSet = new LinkedHashSet(); + reorderedStructuresSet.addAll(filteredResponse); + reorderedStructuresSet.addAll(discoveredStructuresSet); + tbl_summary.setModel(PDBRestResponse.getTableModel( + lastPdbRequest, reorderedStructuresSet)); + + // Update table selection model here + tbl_summary.addRowSelectionInterval(0, filterResponseCount - 1); + + } + + lbl_loading.setVisible(false); + String totalTime = (System.currentTimeMillis() - startTime) + + " milli secs"; + mainFrame.setTitle("Structure Chooser - Filter time (" + + totalTime + ")"); + + validateSelections(); + } catch (Exception e) + { + e.printStackTrace(); + } + } + }); + filterThread.start(); + } + + + /** + * Handles action event for btn_pdbFromFile + */ + public void pdbFromFile_actionPerformed() + { + jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser( + jalview.bin.Cache.getProperty("LAST_DIRECTORY")); + chooser.setFileView(new jalview.io.JalviewFileView()); + chooser.setDialogTitle(MessageManager.formatMessage( + "label.select_pdb_file_for", new String[] + { selectedSequence.getDisplayId(false) })); + chooser.setToolTipText(MessageManager.formatMessage( + "label.load_pdb_file_associate_with_sequence", new String[] + { selectedSequence.getDisplayId(false) })); + + int value = chooser.showOpenDialog(null); + if (value == jalview.io.JalviewFileChooser.APPROVE_OPTION) + { + selectedPdbFileName = chooser.getSelectedFile().getPath(); + jalview.bin.Cache.setProperty("LAST_DIRECTORY", selectedPdbFileName); + validateSelections(); + } + } + + /** + * Populates the filter combo-box options dynamically depending on discovered + * structures + */ + protected void populateFilterComboBox() + { + if (isStructuresDiscovered()) + { + cmb_filterOption.addItem(new FilterOption("Best Quality", + PDBDocField.OVERALL_QUALITY.getCode(), VIEWS_FILTER)); + cmb_filterOption.addItem(new FilterOption("Best UniProt Coverage", + PDBDocField.UNIPROT_COVERAGE.getCode(), VIEWS_FILTER)); + cmb_filterOption.addItem(new FilterOption("Highest Resolution", + PDBDocField.RESOLUTION.getCode(), VIEWS_FILTER)); + cmb_filterOption.addItem(new FilterOption("Highest Protein Chain", + PDBDocField.PROTEIN_CHAIN_COUNT.getCode(), VIEWS_FILTER)); + cmb_filterOption.addItem(new FilterOption("Highest Bound Molecules", + PDBDocField.BOUND_MOLECULE_COUNT.getCode(), VIEWS_FILTER)); + cmb_filterOption.addItem(new FilterOption("Highest Polymer Residues", + PDBDocField.POLYMER_RESIDUE_COUNT.getCode(), VIEWS_FILTER)); + } + cmb_filterOption.addItem(new FilterOption("Enter PDB Id", "-", + VIEWS_ENTER_ID)); + cmb_filterOption.addItem(new FilterOption("From File", "-", + VIEWS_FROM_FILE)); + } + + /** + * Updates the displayed view based on the selected filter option + */ + protected void updateCurrentView() + { + FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption + .getSelectedItem()); + layout_switchableViews.show(pnl_switchableViews, + selectedFilterOpt.getView()); + String filterTitle = mainFrame.getTitle(); + mainFrame.setTitle(frameTitle); + chk_invertFilter.setVisible(false); + if (selectedFilterOpt.getView() == VIEWS_FILTER) + { + mainFrame.setTitle(filterTitle); + chk_invertFilter.setVisible(true); + filterResultSet(selectedFilterOpt.getValue()); + } + else + { + idInputAssSeqPanel.loadCmbAssSeq(); + fileChooserAssSeqPanel.loadCmbAssSeq(); + } + validateSelections(); + } + + /** + * Validates user selection and activates the view button if all parameters + * are correct + */ + public void validateSelections() + { + FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption + .getSelectedItem()); + btn_view.setEnabled(false); + String currentView = selectedFilterOpt.getView(); + if (currentView == VIEWS_FILTER) + { + if (tbl_summary.getSelectedRows().length > 0) + { + btn_view.setEnabled(true); + } + } + else if (currentView == VIEWS_ENTER_ID) + { + validateAssociationEnterPdb(); + } + else if (currentView == VIEWS_FROM_FILE) + { + validateAssociationFromFile(); + } + } + + /** + * Validates inputs from the Manual PDB entry panel + */ + public void validateAssociationEnterPdb() + { + AssociateSeqOptions assSeqOpt = (AssociateSeqOptions) idInputAssSeqPanel + .getCmb_assSeq().getSelectedItem(); + lbl_pdbManualFetchStatus.setIcon(errorImage); + if (selectedSequences.length == 1 + || !assSeqOpt.getName().equalsIgnoreCase( + "-Select Associated Seq-")) + { + txt_search.setEnabled(true); + if (isValidPBDEntry) + { + btn_view.setEnabled(true); + lbl_pdbManualFetchStatus.setIcon(goodImage); + } + } + else + { + txt_search.setEnabled(false); + lbl_pdbManualFetchStatus.setIcon(errorImage); + } + } + + /** + * Validates inputs for the manual PDB file selection options + */ + public void validateAssociationFromFile() + { + AssociateSeqOptions assSeqOpt = (AssociateSeqOptions) fileChooserAssSeqPanel + .getCmb_assSeq().getSelectedItem(); + lbl_fromFileStatus.setIcon(errorImage); + if (selectedSequences.length == 1 + || (assSeqOpt != null + && !assSeqOpt.getName().equalsIgnoreCase( + "-Select Associated Seq-"))) + { + btn_pdbFromFile.setEnabled(true); + if (selectedPdbFileName != null && selectedPdbFileName.length() > 0) + { + btn_view.setEnabled(true); + lbl_fromFileStatus.setIcon(goodImage); + } + } + else + { + btn_pdbFromFile.setEnabled(false); + lbl_fromFileStatus.setIcon(errorImage); + } + } + + @Override + public void cmbAssSeqStateChanged() + { + validateSelections(); + } + + /** + * Handles the state change event for the 'filter' combo-box and 'invert' + * check-box + */ + @Override + protected void stateChanged(ItemEvent e) + { + if (e.getSource() instanceof JCheckBox) + { + updateCurrentView(); + } + else + { + if (e.getStateChange() == ItemEvent.SELECTED) + { + updateCurrentView(); + } + } + + } + + /** + * Handles action event for btn_ok + */ + @Override + public void ok_ActionPerformed() + { + FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption + .getSelectedItem()); + String currentView = selectedFilterOpt.getView(); + if (currentView == VIEWS_FILTER) + { + int pdbIdCol = PDBRestClient.getPDBIdColumIndex( + lastPdbRequest.getWantedFields(), true); + int[] selectedRows = tbl_summary.getSelectedRows(); + PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length]; + int count = 0; + for (int summaryRow : selectedRows) + { + String pdbIdStr = tbl_summary.getValueAt(summaryRow, pdbIdCol) + .toString(); + PDBEntry pdbEntry = new PDBEntry(); + pdbEntry.setId(pdbIdStr); + pdbEntry.setType("PDB"); + pdbEntriesToView[count++] = pdbEntry; + } + new StructureViewer(ap.getStructureSelectionManager()) + .viewStructures(ap, pdbEntriesToView, + ap.av.collateForPDB(pdbEntriesToView)); + } + else if (currentView == VIEWS_ENTER_ID) + { + selectedSequence = ((AssociateSeqOptions) idInputAssSeqPanel + .getCmb_assSeq().getSelectedItem()).getSequence(); + PDBEntry pdbEntry = new PDBEntry(); + pdbEntry.setId(txt_search.getText()); + pdbEntry.setType("PDB"); + selectedSequence.getDatasetSequence().addPDBId(pdbEntry); + PDBEntry[] pdbEntriesToView = new PDBEntry[] + { pdbEntry }; + new StructureViewer(ap.getStructureSelectionManager()) + .viewStructures(ap, pdbEntriesToView, + ap.av.collateForPDB(pdbEntriesToView)); + } + else if (currentView == VIEWS_FROM_FILE) + { + selectedSequence = ((AssociateSeqOptions) fileChooserAssSeqPanel + .getCmb_assSeq().getSelectedItem()).getSequence(); + new AssociatePdbFileWithSeq().associatePdbWithSeq( + selectedPdbFileName, jalview.io.AppletFormatAdapter.FILE, + selectedSequence, true, Desktop.instance); + } + mainFrame.dispose(); + } + + /** + * Populates the combo-box used in associating manually fetched structures to + * a unique sequence when more than one sequence selection is made. + */ + public void populateCmbAssociateSeqOptions( + JComboBox cmb_assSeq, JLabel lbl_associateSeq) + { + cmb_assSeq.removeAllItems(); + cmb_assSeq.addItem(new AssociateSeqOptions("-Select Associated Seq-", + null)); + // cmb_assSeq.addItem(new AssociateSeqOptions("Auto Detect", null)); + lbl_associateSeq.setVisible(false); + if (selectedSequences.length > 1) + { + for (SequenceI seq : selectedSequences) + { + cmb_assSeq.addItem(new AssociateSeqOptions(seq)); + } + } + else + { + String seqName = selectedSequence.getDisplayId(false); + seqName = seqName.length() <= 40 ? seqName : seqName.substring(0, 39); + lbl_associateSeq.setText(seqName); + lbl_associateSeq.setVisible(true); + cmb_assSeq.setVisible(false); + } + } + + public boolean isStructuresDiscovered() + { + return structuresDiscovered; + } + + public void setStructuresDiscovered(boolean structuresDiscovered) + { + this.structuresDiscovered = structuresDiscovered; + } + + public Collection getDiscoveredStructuresSet() + { + return discoveredStructuresSet; + } + + @Override + protected void txt_search_ActionPerformed() + { + isValidPBDEntry = false; + if (txt_search.getText().length() > 0) + { + List wantedFields = new ArrayList(); + wantedFields.add(PDBDocField.PDB_ID); + PDBRestRequest pdbRequest = new PDBRestRequest(); + pdbRequest.setAllowEmptySeq(false); + pdbRequest.setResponseSize(1); + pdbRequest.setFieldToSearchBy("(pdb_id:"); + pdbRequest.setWantedFields(wantedFields); + pdbRequest.setSearchTerm(txt_search.getText() + ")"); + pdbRequest.setAssociatedSequence(selectedSequence.getName()); + pdbRestCleint = new PDBRestClient(); + PDBRestResponse resultList = pdbRestCleint.executeRequest(pdbRequest); + if (resultList.getSearchSummary() != null + && resultList.getSearchSummary().size() > 0) + { + isValidPBDEntry = true; + } + } + validateSelections(); + } + + @Override + public void tabRefresh() + { + if (selectedSequences != null) + { + Thread refreshThread = new Thread(new Runnable() + { + @Override + public void run() + { + fetchStructuresMetaData(); + filterResultSet(((FilterOption) cmb_filterOption + .getSelectedItem()).getValue()); + } + }); + refreshThread.start(); + } + } + +} diff --git a/src/jalview/gui/TextColourChooser.java b/src/jalview/gui/TextColourChooser.java index 0b5f34d..c8a4a08 100644 --- a/src/jalview/gui/TextColourChooser.java +++ b/src/jalview/gui/TextColourChooser.java @@ -20,14 +20,24 @@ */ package jalview.gui; -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.event.*; - -import jalview.datamodel.*; +import jalview.datamodel.SequenceGroup; import jalview.util.MessageManager; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.BorderFactory; +import javax.swing.JColorChooser; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JSlider; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + public class TextColourChooser { AlignmentPanel ap; @@ -42,9 +52,9 @@ public class TextColourChooser int original1, original2, originalThreshold; if (sg == null) { - original1 = ap.av.textColour.getRGB(); - original2 = ap.av.textColour2.getRGB(); - originalThreshold = ap.av.thresholdTextColour; + original1 = ap.av.getTextColour().getRGB(); + original2 = ap.av.getTextColour2().getRGB(); + originalThreshold = ap.av.getThresholdTextColour(); } else { @@ -119,9 +129,9 @@ public class TextColourChooser { if (sg == null) { - ap.av.textColour = new Color(original1); - ap.av.textColour2 = new Color(original2); - ap.av.thresholdTextColour = originalThreshold; + ap.av.setTextColour(new Color(original1)); + ap.av.setTextColour2(new Color(original2)); + ap.av.setThresholdTextColour(originalThreshold); } else { @@ -136,7 +146,7 @@ public class TextColourChooser { if (sg == null) { - ap.av.textColour = col; + ap.av.setTextColour(col); if (ap.av.getColourAppliesToAllGroups()) { setGroupTextColour(); @@ -154,7 +164,7 @@ public class TextColourChooser { if (sg == null) { - ap.av.textColour2 = col; + ap.av.setTextColour2(col); if (ap.av.getColourAppliesToAllGroups()) { setGroupTextColour(); @@ -172,7 +182,7 @@ public class TextColourChooser { if (sg == null) { - ap.av.thresholdTextColour = value; + ap.av.setThresholdTextColour(value); if (ap.av.getColourAppliesToAllGroups()) { setGroupTextColour(); @@ -195,9 +205,9 @@ public class TextColourChooser for (SequenceGroup sg : ap.av.getAlignment().getGroups()) { - sg.textColour = ap.av.textColour; - sg.textColour2 = ap.av.textColour2; - sg.thresholdTextColour = ap.av.thresholdTextColour; + sg.textColour = ap.av.getTextColour(); + sg.textColour2 = ap.av.getTextColour2(); + sg.thresholdTextColour = ap.av.getThresholdTextColour(); } } diff --git a/src/jalview/gui/TreeCanvas.java b/src/jalview/gui/TreeCanvas.java index b3a0a75..1bce84b 100755 --- a/src/jalview/gui/TreeCanvas.java +++ b/src/jalview/gui/TreeCanvas.java @@ -20,17 +20,47 @@ */ package jalview.gui; -import java.util.*; - -import java.awt.*; -import java.awt.event.*; -import java.awt.print.*; -import javax.swing.*; - -import jalview.analysis.*; -import jalview.datamodel.*; -import jalview.schemes.*; -import jalview.util.*; +import jalview.analysis.Conservation; +import jalview.analysis.NJTree; +import jalview.api.AlignViewportI; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; +import jalview.datamodel.SequenceNode; +import jalview.schemes.ColourSchemeI; +import jalview.schemes.ColourSchemeProperty; +import jalview.schemes.ResidueProperties; +import jalview.schemes.UserColourScheme; +import jalview.structure.SelectionSource; +import jalview.util.Format; +import jalview.util.MappingUtils; +import jalview.util.MessageManager; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + +import javax.swing.JColorChooser; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; +import javax.swing.ToolTipManager; /** * DOCUMENT ME! @@ -39,7 +69,7 @@ import jalview.util.*; * @version $Revision$ */ public class TreeCanvas extends JPanel implements MouseListener, Runnable, - Printable, MouseMotionListener + Printable, MouseMotionListener, SelectionSource { /** DOCUMENT ME!! */ public static final String PLACEHOLDER = " * "; @@ -208,7 +238,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, if (node.element() instanceof SequenceI) { - SequenceI seq = (SequenceI) ((SequenceNode) node).element(); + SequenceI seq = (SequenceI) node.element(); if (av.getSequenceColour(seq) == Color.white) { @@ -258,14 +288,14 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, Rectangle rect = new Rectangle(xend + 10, ypos - charHeight / 2, charWidth, charHeight); - nameHash.put((SequenceI) node.element(), rect); + nameHash.put(node.element(), rect); // Colour selected leaves differently SequenceGroup selected = av.getSelectionGroup(); if ((selected != null) && selected.getSequences(null).contains( - (SequenceI) node.element())) + node.element())) { g.setColor(Color.gray); @@ -290,7 +320,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, int xend = (int) (height * scale) + offx; int ypos = (int) (node.ycount * chunk) + offy; - g.setColor(((SequenceNode) node).color.darker()); + g.setColor(node.color.darker()); // Draw horizontal line g.drawLine(xstart, ypos, xend, ypos); @@ -493,7 +523,8 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, { for (int a = 0; a < aps.length; a++) { - aps[a].av.setSequenceColour((SequenceI) node.element(), c); + final SequenceI seq = (SequenceI) node.element(); + aps[a].av.setSequenceColour(seq, c); } } } @@ -682,7 +713,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, labelLength = fm.stringWidth(longestName) + 20; // 20 allows for scrollbar - float wscale = (float) (width - labelLength - (offx * 2)) + float wscale = (width - labelLength - (offx * 2)) / tree.getMaxHeight(); SequenceNode top = tree.getTopNode(); @@ -708,7 +739,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, g2.setColor(Color.gray); } - int x = (int) ((threshold * (float) (getWidth() - labelLength - (2 * offx))) + offx); + int x = (int) ((threshold * (getWidth() - labelLength - (2 * offx))) + offx); g2.drawLine(x, 0, x, getHeight()); } @@ -854,12 +885,20 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, AlignmentPanel[] aps = getAssociatedPanels(); + // TODO push calls below into a single AlignViewportI method? + // see also AlignViewController.deleteGroups for (int a = 0; a < aps.length; a++) { aps[a].av.setSelectionGroup(null); aps[a].av.getAlignment().deleteAllGroups(); aps[a].av.clearSequenceColours(); } + if (av.getCodingComplement() != null) + { + av.getCodingComplement().setSelectionGroup(null); + av.getCodingComplement().getAlignment().deleteAllGroups(); + av.getCodingComplement().clearSequenceColours(); + } colourGroups(); } @@ -916,13 +955,14 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, if (cs != null) { cs.setThreshold(av.getGlobalColourScheme().getThreshold(), - av.getIgnoreGapsConsensus()); + av.isIgnoreGapsConsensus()); } } sg.cs = cs; // sg.recalcConservation(); sg.setName("JTreeGroup:" + sg.hashCode()); sg.setIdColour(col); + for (int a = 0; a < aps.length; a++) { if (aps[a].av.getGlobalColourScheme() != null @@ -939,7 +979,25 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, aps[a].av.getAlignment().addGroup(new SequenceGroup(sg)); } + + // TODO can we push all of the below into AlignViewportI? + av.getAlignment().addGroup(sg); + final AlignViewportI codingComplement = av.getCodingComplement(); + if (codingComplement != null) + { + SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, av, + codingComplement); + if (mappedGroup.getSequences().size() > 0) + { + codingComplement.getAlignment().addGroup(mappedGroup); + for (SequenceI seq : mappedGroup.getSequences()) + { + codingComplement.setSequenceColour(seq, col.brighter()); + } + } + } } + // notify the panel to redo any group specific stuff. for (int a = 0; a < aps.length; a++) { @@ -948,6 +1006,13 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, // to any Jmols listening in } + if (av.getCodingComplement() != null) + { + ((AlignViewport) av.getCodingComplement()).getAlignPanel().updateAnnotation(); + /* + * idPanel. repaint () + */ + } } /** diff --git a/src/jalview/gui/TreePanel.java b/src/jalview/gui/TreePanel.java index b8eba8f..7177e43 100755 --- a/src/jalview/gui/TreePanel.java +++ b/src/jalview/gui/TreePanel.java @@ -43,6 +43,7 @@ import jalview.io.NewickFile; import jalview.jbgui.GTreePanel; import jalview.schemes.ResidueProperties; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.awt.Font; import java.awt.Graphics; @@ -138,7 +139,7 @@ public class TreePanel extends GTreePanel return treeCanvas.av.getAlignment(); } - public AlignViewport getViewPort() + public AlignmentViewport getViewPort() { return treeCanvas.av; } @@ -242,7 +243,8 @@ public class TreePanel extends GTreePanel associateLeavesMenu.add(item); } - final JRadioButtonMenuItem itemf = new JRadioButtonMenuItem("All Views"); + final JRadioButtonMenuItem itemf = new JRadioButtonMenuItem( + "label.all_views"); buttonGroup.add(itemf); itemf.setSelected(treeCanvas.applyToAllViews); itemf.addActionListener(new ActionListener() @@ -343,7 +345,7 @@ public class TreePanel extends GTreePanel av.setCurrentTree(tree); if (av.getSortByTree()) { - sortByTree_actionPerformed(null); + sortByTree_actionPerformed(); } } } @@ -531,7 +533,7 @@ public class TreePanel extends GTreePanel // msaorder); Desktop.addInternalFrame(af, MessageManager.formatMessage( - "label.original_data_for_params", new String[] + "label.original_data_for_params", new Object[] { this.title }), AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); } @@ -555,7 +557,8 @@ public class TreePanel extends GTreePanel * * @param e */ - public void sortByTree_actionPerformed(ActionEvent e) + @Override + public void sortByTree_actionPerformed() { if (treeCanvas.applyToAllViews) @@ -617,7 +620,7 @@ public class TreePanel extends GTreePanel public CommandI sortAlignmentIn(AlignmentPanel ap) { - AlignViewport av = ap.av; + AlignmentViewport av = ap.av; SequenceI[] oldOrder = av.getAlignment().getSequencesArray(); AlignmentSorter.sortByTree(av.getAlignment(), tree); CommandI undo; diff --git a/src/jalview/gui/UserDefinedColours.java b/src/jalview/gui/UserDefinedColours.java index d7a521c..c5562c6 100755 --- a/src/jalview/gui/UserDefinedColours.java +++ b/src/jalview/gui/UserDefinedColours.java @@ -528,7 +528,7 @@ public class UserDefinedColours extends GUserDefinedColours implements } }else{ for (int i = 0; i < 24; i++){ - JButton button = (JButton) upperCaseButtons.get(i); + JButton button = upperCaseButtons.get(i); newColours[i] = button.getBackground(); } } @@ -547,7 +547,7 @@ public class UserDefinedColours extends GUserDefinedColours implements } }else{ for (int i = 0; i < 23; i++){ - JButton button = (JButton) lowerCaseButtons.get(i); + JButton button = lowerCaseButtons.get(i); newColours[i] = button.getBackground(); } } @@ -556,7 +556,7 @@ public class UserDefinedColours extends GUserDefinedColours implements if (ap != null) { - ucs.setThreshold(0, ap.av.getIgnoreGapsConsensus()); + ucs.setThreshold(0, ap.av.isIgnoreGapsConsensus()); } return ucs; diff --git a/src/jalview/gui/VamsasApplication.java b/src/jalview/gui/VamsasApplication.java index 3671b39..6444667 100644 --- a/src/jalview/gui/VamsasApplication.java +++ b/src/jalview/gui/VamsasApplication.java @@ -32,12 +32,12 @@ import jalview.structure.StructureSelectionManager; import jalview.structure.VamsasListener; import jalview.structure.VamsasSource; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; -import java.util.Enumeration; import java.util.Hashtable; import java.util.IdentityHashMap; import java.util.Iterator; @@ -347,7 +347,9 @@ public class VamsasApplication implements SelectionSource, VamsasSource public void end_session(boolean promptUser) { if (!inSession()) + { throw new Error(MessageManager.getString("error.jalview_no_connected_vamsas_session")); + } Cache.log.info("Jalview disconnecting from the Vamsas Session."); try { @@ -958,11 +960,14 @@ public class VamsasApplication implements SelectionSource, VamsasSource int i = -1; - public void mouseOver(SequenceI seq, int index, + @Override + public void mouseOverSequence(SequenceI seq, int index, VamsasSource source) { if (jv2vobj == null) + { return; + } if (seq != last || i != index) { VorbaId v = (VorbaId) jv2vobj.get(seq); @@ -998,7 +1003,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource AlignmentI visal = null; if (source instanceof AlignViewport) { - visal = ((AlignViewport) source).getAlignment(); + visal = ((AlignmentViewport) source).getAlignment(); } SelectionMessage sm = null; if ((seqsel == null || seqsel.getSize() == 0) @@ -1009,7 +1014,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource { // the empty selection. sm = new SelectionMessage("jalview", new String[] - { ((AlignViewport) source).getSequenceSetId() }, null, + { ((AlignmentViewport) source).getSequenceSetId() }, null, true); } else @@ -1050,10 +1055,9 @@ public class VamsasApplication implements SelectionSource, VamsasSource { // gather selected columns outwith the sequence positions // too - Enumeration cols = colsel.getSelected().elements(); - while (cols.hasMoreElements()) + for (Object obj : colsel.getSelected()) { - int ival = ((Integer) cols.nextElement()).intValue(); + int ival = ((Integer) obj).intValue(); Pos p = new Pos(); p.setI(ival + 1); range.addPos(p); diff --git a/src/jalview/gui/WsJobParameters.java b/src/jalview/gui/WsJobParameters.java index 07e3a9b..ff03fef 100644 --- a/src/jalview/gui/WsJobParameters.java +++ b/src/jalview/gui/WsJobParameters.java @@ -1306,7 +1306,7 @@ public class WsJobParameters extends JPanel implements ItemListener, */ protected void updateWebServiceMenus() { - for (AlignFrame alignFrame : Desktop.getAlignframes()) + for (AlignFrame alignFrame : Desktop.getAlignFrames()) { alignFrame.BuildWebServiceMenu(); } diff --git a/src/jalview/io/AppletFormatAdapter.java b/src/jalview/io/AppletFormatAdapter.java index d076b7a..c69a0c7 100755 --- a/src/jalview/io/AppletFormatAdapter.java +++ b/src/jalview/io/AppletFormatAdapter.java @@ -46,10 +46,24 @@ public class AppletFormatAdapter * List of valid format strings used in the isValidFormat method */ public static final String[] READABLE_FORMATS = new String[] - { "BLC", "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "STH", - "PDB", "JnetFile", "RNAML", PhylipFile.FILE_DESC, "HTML" }; // , - // "SimpleBLAST" - // }; + { "BLC", "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "STH", + "PDB", "JnetFile", "RNAML", PhylipFile.FILE_DESC, "HTML" }; + + /** + * List of readable format file extensions by application in order + * corresponding to READABLE_FNAMES + */ + public static final String[] READABLE_EXTENSIONS = new String[] + { "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa", + "sto,stk", "xml,rnaml", PhylipFile.FILE_EXT, "jar,jvp", "html" }; + + /** + * List of readable formats by application in order corresponding to + * READABLE_EXTENSIONS + */ + public static final String[] READABLE_FNAMES = new String[] + { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "Stockholm", + "RNAML", PhylipFile.FILE_DESC, "Jalview", "HTML" }; /** * List of valid format strings for use by callers of the formatSequences @@ -75,26 +89,6 @@ public class AppletFormatAdapter { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "STH", PhylipFile.FILE_DESC, "Jalview" }; - /** - * List of readable format file extensions by application in order - * corresponding to READABLE_FNAMES - */ - public static final String[] READABLE_EXTENSIONS = new String[] - { "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa", - "jar,jvp", "sto,stk", "xml,rnaml", PhylipFile.FILE_EXT, - "html" }; // ".blast" - - /** - * List of readable formats by application in order corresponding to - * READABLE_EXTENSIONS - */ - public static final String[] READABLE_FNAMES = new String[] - { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "Jalview", - "Stockholm", "RNAML", PhylipFile.FILE_DESC, "HTML" };// , - - // "SimpleBLAST" - // }; - public static String INVALID_CHARACTERS = "Contains invalid characters"; // TODO: make these messages dynamic diff --git a/src/jalview/io/BioJsHTMLOutput.java b/src/jalview/io/BioJsHTMLOutput.java index db43a3f..d2c4a7f 100644 --- a/src/jalview/io/BioJsHTMLOutput.java +++ b/src/jalview/io/BioJsHTMLOutput.java @@ -5,7 +5,6 @@ import jalview.datamodel.AlignmentI; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.exceptions.NoFileSelectedException; -import jalview.gui.AlignViewport; import jalview.gui.AlignmentPanel; import jalview.gui.FeatureRenderer; import jalview.json.binding.v1.BioJsAlignmentPojo; @@ -13,6 +12,7 @@ import jalview.json.binding.v1.BioJsFeaturePojo; import jalview.json.binding.v1.BioJsSeqPojo; import jalview.schemes.ColourSchemeProperty; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.awt.Color; import java.io.BufferedReader; @@ -26,7 +26,7 @@ import com.json.JSONException; public class BioJsHTMLOutput { - private AlignViewport av; + private AlignmentViewport av; private jalview.api.FeatureRenderer fr; @@ -137,8 +137,7 @@ public class BioJsHTMLOutput seqPojo.setName(name.toString()); seqPojo.setSeq(seq.getSequenceAsString()); - SequenceFeature[] seqFeatures = seq.getDatasetSequence() - .getSequenceFeatures(); + SequenceFeature[] seqFeatures = seq.getSequenceFeatures(); if (seqFeatures != null) { ArrayList bjsSeqFeatures = new ArrayList(); diff --git a/src/jalview/io/FileLoader.java b/src/jalview/io/FileLoader.java index 38033ff..3322689 100755 --- a/src/jalview/io/FileLoader.java +++ b/src/jalview/io/FileLoader.java @@ -332,13 +332,7 @@ public class FileLoader implements Runnable } if (viewport != null) { - // TODO: create undo object for this JAL-1101 - for (int i = 0; i < al.getHeight(); i++) - { - viewport.getAlignment().addSequence(al.getSequenceAt(i)); - } - viewport.firePropertyChange("alignment", null, viewport - .getAlignment().getSequences()); + viewport.addAlignment(al, title); } else { diff --git a/src/jalview/io/MSFfile.java b/src/jalview/io/MSFfile.java index c81be4b..3de5b30 100755 --- a/src/jalview/io/MSFfile.java +++ b/src/jalview/io/MSFfile.java @@ -20,11 +20,14 @@ */ package jalview.io; -import java.io.*; -import java.util.*; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; +import jalview.util.Format; -import jalview.datamodel.*; -import jalview.util.*; +import java.io.IOException; +import java.util.Hashtable; +import java.util.StringTokenizer; +import java.util.Vector; /** * DOCUMENT ME! @@ -63,10 +66,6 @@ public class MSFfile extends AlignFile super(source); } - { - // TODO Auto-generated constructor stub - } - /** * DOCUMENT ME! */ diff --git a/src/jalview/io/SequenceAnnotationReport.java b/src/jalview/io/SequenceAnnotationReport.java index 610c03f..07cfa8b 100644 --- a/src/jalview/io/SequenceAnnotationReport.java +++ b/src/jalview/io/SequenceAnnotationReport.java @@ -20,6 +20,7 @@ */ package jalview.io; + import java.util.ArrayList; import java.util.Hashtable; import java.util.List; @@ -364,7 +365,7 @@ public class SequenceAnnotationReport } // ADD NON POSITIONAL SEQUENCE INFO - SequenceFeature[] features = ds.getSequenceFeatures(); + SequenceFeature[] features = sequence.getSequenceFeatures(); if (showNpFeats && features != null) { for (int i = 0; i < features.length; i++) diff --git a/src/jalview/io/StockholmFile.java b/src/jalview/io/StockholmFile.java index e5e14ad..6490d28 100644 --- a/src/jalview/io/StockholmFile.java +++ b/src/jalview/io/StockholmFile.java @@ -978,6 +978,7 @@ public class StockholmFile extends AlignFile { feature = ds.getSequenceFeatures()[0].type; } + // ?bug - feature may still have previous loop value String key = type2id(feature); if (key == null) diff --git a/src/jalview/io/VamsasAppDatastore.java b/src/jalview/io/VamsasAppDatastore.java index 58adfb2..7df7cb2 100644 --- a/src/jalview/io/VamsasAppDatastore.java +++ b/src/jalview/io/VamsasAppDatastore.java @@ -34,6 +34,7 @@ import jalview.io.vamsas.DatastoreItem; import jalview.io.vamsas.DatastoreRegistry; import jalview.io.vamsas.Rangetype; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.io.IOException; import java.util.Enumeration; @@ -42,12 +43,35 @@ import java.util.Hashtable; import java.util.IdentityHashMap; import java.util.Iterator; import java.util.List; +import java.util.Set; import java.util.Vector; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; -import uk.ac.vamsas.client.*; -import uk.ac.vamsas.objects.core.*; +import uk.ac.vamsas.client.IClientAppdata; +import uk.ac.vamsas.client.IClientDocument; +import uk.ac.vamsas.client.Vobject; +import uk.ac.vamsas.client.VorbaId; +import uk.ac.vamsas.objects.core.Alignment; +import uk.ac.vamsas.objects.core.AlignmentSequence; +import uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation; +import uk.ac.vamsas.objects.core.AnnotationElement; +import uk.ac.vamsas.objects.core.DataSet; +import uk.ac.vamsas.objects.core.DataSetAnnotations; +import uk.ac.vamsas.objects.core.DbRef; +import uk.ac.vamsas.objects.core.Entry; +import uk.ac.vamsas.objects.core.Glyph; +import uk.ac.vamsas.objects.core.Local; +import uk.ac.vamsas.objects.core.MapType; +import uk.ac.vamsas.objects.core.Mapped; +import uk.ac.vamsas.objects.core.Property; +import uk.ac.vamsas.objects.core.Provenance; +import uk.ac.vamsas.objects.core.RangeAnnotation; +import uk.ac.vamsas.objects.core.RangeType; +import uk.ac.vamsas.objects.core.Seg; +import uk.ac.vamsas.objects.core.Sequence; +import uk.ac.vamsas.objects.core.SequenceType; +import uk.ac.vamsas.objects.core.VAMSAS; import uk.ac.vamsas.objects.utils.Properties; /* @@ -127,7 +151,7 @@ public class VamsasAppDatastore private void buildSkipList() { skipList = new Hashtable(); - AlignFrame[] al = Desktop.getAlignframes(); + AlignFrame[] al = Desktop.getAlignFrames(); for (int f = 0; al != null && f < al.length; f++) { skipList.put(al[f].getViewport().getSequenceSetId(), al[f]); @@ -728,12 +752,12 @@ public class VamsasAppDatastore * @return true if alignment associated with this view will be stored in * document. */ - public boolean alignmentWillBeSkipped(AlignViewport av) + public boolean alignmentWillBeSkipped(AlignmentViewport av) { return (!av.getAlignment().isAligned()); } - private void addToSkipList(AlignViewport av) + private void addToSkipList(AlignmentViewport av) { if (skipList == null) { @@ -1068,8 +1092,10 @@ public class VamsasAppDatastore an.addProperty(Properties.newProperty(THRESHOLD, Properties.FLOATTYPE, "" + alan.getThreshold().value)); if (alan.getThreshold().label != null) + { an.addProperty(Properties.newProperty(THRESHOLD + "Name", Properties.STRINGTYPE, "" + alan.getThreshold().label)); + } } ((DataSet) sref.getV_parent()).addDataSetAnnotations(an); bindjvvobj(alan, an); @@ -1381,12 +1407,12 @@ public class VamsasAppDatastore // sync, // and if any contain more than one view, then remove the one generated by // document update. - AlignViewport views[], av = null; + AlignmentViewport views[], av = null; AlignFrame af = null; Iterator newviews = newAlignmentViews.iterator(); while (newviews.hasNext()) { - av = (AlignViewport) newviews.next(); + av = (AlignmentViewport) newviews.next(); af = Desktop.getAlignFrameFor(av); // TODO implement this : af.getNumberOfViews String seqsetidobj = av.getSequenceSetId(); @@ -1403,7 +1429,8 @@ public class VamsasAppDatastore // to the align frames. boolean gathered = false; String newviewid = null; - AlignedCodonFrame[] mappings = av.getAlignment().getCodonFrames(); + Set mappings = av.getAlignment() + .getCodonFrames(); for (int i = 0; i < views.length; i++) { if (views[i] != av) @@ -1438,7 +1465,7 @@ public class VamsasAppDatastore { // ensure sequence mappings from vamsas document view still // active - if (mappings != null && mappings.length > 0) + if (mappings != null) { jalview.structure.StructureSelectionManager .getStructureSelectionManager(Desktop.instance) @@ -1682,7 +1709,7 @@ public class VamsasAppDatastore uk.ac.vamsas.objects.core.Alignment alignment = dataset .getAlignment(al); // TODO check this handles multiple views properly - AlignViewport av = findViewport(alignment); + AlignmentViewport av = findViewport(alignment); jalview.datamodel.AlignmentI jal = null; if (av != null) @@ -1956,10 +1983,10 @@ public class VamsasAppDatastore return newAlignmentViews.size(); } - public AlignViewport findViewport(Alignment alignment) + public AlignmentViewport findViewport(Alignment alignment) { - AlignViewport av = null; - AlignViewport[] avs = Desktop + AlignmentViewport av = null; + AlignmentViewport[] avs = Desktop .getViewports((String) getvObj2jv(alignment)); if (avs != null) { @@ -2207,6 +2234,7 @@ public class VamsasAppDatastore Cache.log.warn("Failed to parse threshold property"); } if (val != null) + { if (gl == null) { gl = new GraphLine(val.floatValue(), "", java.awt.Color.black); @@ -2215,11 +2243,14 @@ public class VamsasAppDatastore { gl.value = val.floatValue(); } + } } else if (props[p].getName().equalsIgnoreCase(THRESHOLD + "Name")) { if (gl == null) + { gl = new GraphLine(0, "", java.awt.Color.black); + } gl.label = props[p].getContent(); } } @@ -2539,15 +2570,15 @@ public class VamsasAppDatastore * initialise a range type object from a set of start/end inclusive intervals * * @param mrt - * @param range + * @param ranges */ - private void initRangeType(RangeType mrt, int[] range) + private void initRangeType(RangeType mrt, List ranges) { - for (int i = 0; i < range.length; i += 2) + for (int[] range : ranges) { Seg vSeg = new Seg(); - vSeg.setStart(range[i]); - vSeg.setEnd(range[i + 1]); + vSeg.setStart(range[0]); + vSeg.setEnd(range[1]); mrt.addSeg(vSeg); } } @@ -2670,10 +2701,10 @@ public class VamsasAppDatastore return vobj2jv; } - public void storeSequenceMappings(AlignViewport viewport, String title) + public void storeSequenceMappings(AlignmentViewport viewport, String title) throws Exception { - AlignViewport av = viewport; + AlignmentViewport av = viewport; try { jalview.datamodel.AlignmentI jal = av.getAlignment(); @@ -2695,18 +2726,15 @@ public class VamsasAppDatastore } // Store any sequence mappings. - if (av.getAlignment().getCodonFrames() != null - && av.getAlignment().getCodonFrames().length > 0) + Set cframes = av.getAlignment().getCodonFrames(); + if (cframes != null) { - jalview.datamodel.AlignedCodonFrame[] cframes = av.getAlignment() - .getCodonFrames(); - for (int cf = 0; cf < cframes.length; cf++) + for (AlignedCodonFrame acf : cframes) { - if (cframes[cf].getdnaSeqs() != null - && cframes[cf].getdnaSeqs().length > 0) + if (acf.getdnaSeqs() != null && acf.getdnaSeqs().length > 0) { - jalview.datamodel.SequenceI[] dmps = cframes[cf].getdnaSeqs(); - jalview.datamodel.Mapping[] mps = cframes[cf].getProtMappings(); + jalview.datamodel.SequenceI[] dmps = acf.getdnaSeqs(); + jalview.datamodel.Mapping[] mps = acf.getProtMappings(); for (int smp = 0; smp < mps.length; smp++) { uk.ac.vamsas.objects.core.SequenceType mfrom = (SequenceType) getjv2vObj(dmps[smp]); diff --git a/src/jalview/io/vamsas/Rangetype.java b/src/jalview/io/vamsas/Rangetype.java index e7f8cf2..08b1b52 100644 --- a/src/jalview/io/vamsas/Rangetype.java +++ b/src/jalview/io/vamsas/Rangetype.java @@ -20,6 +20,10 @@ */ package jalview.io.vamsas; +import jalview.io.VamsasAppDatastore; +import jalview.util.MessageManager; + +import java.util.List; import java.util.Vector; import uk.ac.vamsas.client.Vobject; @@ -28,8 +32,6 @@ import uk.ac.vamsas.objects.core.MapType; import uk.ac.vamsas.objects.core.Mapped; import uk.ac.vamsas.objects.core.RangeType; import uk.ac.vamsas.objects.core.Seg; -import jalview.io.VamsasAppDatastore; -import jalview.util.MessageManager; /** * Enhances DatastoreItem objects with additional functions to do with RangeType @@ -221,15 +223,15 @@ public abstract class Rangetype extends DatastoreItem * initialise a range type object from a set of start/end inclusive intervals * * @param mrt - * @param range + * @param ranges */ - protected void initRangeType(RangeType mrt, int[] range) + protected void initRangeType(RangeType mrt, List ranges) { - for (int i = 0; i < range.length; i += 2) + for (int[] range : ranges) { Seg vSeg = new Seg(); - vSeg.setStart(range[i]); - vSeg.setEnd(range[i + 1]); + vSeg.setStart(range[0]); + vSeg.setEnd(range[1]); vSeg.setInclusive(true); mrt.addSeg(vSeg); } diff --git a/src/jalview/io/vamsas/Sequencemapping.java b/src/jalview/io/vamsas/Sequencemapping.java index 97137f8..4929a06 100644 --- a/src/jalview/io/vamsas/Sequencemapping.java +++ b/src/jalview/io/vamsas/Sequencemapping.java @@ -20,14 +20,15 @@ */ package jalview.io.vamsas; -import java.util.Vector; - import jalview.datamodel.AlignedCodonFrame; +import jalview.datamodel.AlignmentI; import jalview.datamodel.Mapping; import jalview.datamodel.SequenceI; import jalview.gui.Desktop; import jalview.io.VamsasAppDatastore; -import uk.ac.vamsas.client.Vobject; + +import java.util.Vector; + import uk.ac.vamsas.objects.core.AlignmentSequence; import uk.ac.vamsas.objects.core.DataSet; import uk.ac.vamsas.objects.core.Sequence; @@ -283,12 +284,12 @@ public class Sequencemapping extends Rangetype jalview.bin.Cache.log.info("Ignoring non sequence-sequence mapping"); return; } - mobj = this.getvObj2jv((Vobject) sdloc); + mobj = this.getvObj2jv(sdloc); if (mobj instanceof SequenceI) { from = (SequenceI) mobj; } - mobj = this.getvObj2jv((Vobject) sdmap); + mobj = this.getvObj2jv(sdmap); if (mobj instanceof SequenceI) { to = (SequenceI) mobj; @@ -325,19 +326,17 @@ public class Sequencemapping extends Rangetype } // create mapping storage object and make each dataset alignment reference // it. - jalview.datamodel.AlignmentI dsLoc = (jalview.datamodel.AlignmentI) getvObj2jv(sdloc - .getV_parent()); - jalview.datamodel.AlignmentI dsMap = (jalview.datamodel.AlignmentI) getvObj2jv(sdmap - .getV_parent()); - AlignedCodonFrame afc = new AlignedCodonFrame(0); + AlignmentI dsLoc = (AlignmentI) getvObj2jv(sdloc.getV_parent()); + AlignmentI dsMap = (AlignmentI) getvObj2jv(sdmap.getV_parent()); + AlignedCodonFrame acf = new AlignedCodonFrame(); if (dsLoc != null && dsLoc != dsMap) { - dsLoc.addCodonFrame(afc); + dsLoc.addCodonFrame(acf); } if (dsMap != null) { - dsMap.addCodonFrame(afc); + dsMap.addCodonFrame(acf); } // create and add the new mapping to (each) dataset's codonFrame @@ -350,24 +349,22 @@ public class Sequencemapping extends Rangetype mapping = new jalview.util.MapList(mapping.getToRanges(), mapping.getFromRanges(), mapping.getToRatio(), mapping.getFromRatio()); - afc.addMap(to, from, mapping); + acf.addMap(to, from, mapping); } else { mapping = this.parsemapType(sequenceMapping, 3, 1); // correct sense - afc.addMap(from, to, mapping); + acf.addMap(from, to, mapping); } } else { mapping = this.parsemapType(sequenceMapping, 1, 1); // correct sense - afc.addMap(from, to, mapping); + acf.addMap(from, to, mapping); } bindjvvobj(mapping, sequenceMapping); jalview.structure.StructureSelectionManager - .getStructureSelectionManager(Desktop.instance).addMappings( - new AlignedCodonFrame[] - { afc }); + .getStructureSelectionManager(Desktop.instance).addMapping(acf); // Try to link up any conjugate database references in the two sequences // matchConjugateDBRefs(from, to, mapping); // Try to propagate any dbrefs across this mapping. diff --git a/src/jalview/io/vamsas/Tree.java b/src/jalview/io/vamsas/Tree.java index 1cbc848..b5ada26 100644 --- a/src/jalview/io/vamsas/Tree.java +++ b/src/jalview/io/vamsas/Tree.java @@ -35,10 +35,10 @@ import jalview.datamodel.SeqCigar; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; import jalview.datamodel.SequenceNode; -import jalview.gui.AlignViewport; import jalview.gui.TreePanel; import jalview.io.NewickFile; import jalview.io.VamsasAppDatastore; +import jalview.viewmodel.AlignmentViewport; import uk.ac.vamsas.client.Vobject; import uk.ac.vamsas.objects.core.AlignmentSequence; import uk.ac.vamsas.objects.core.Entry; @@ -510,7 +510,7 @@ public class Tree extends DatastoreItem */ public Object[] recoverInputData(Provenance tp) { - AlignViewport javport = null; + AlignmentViewport javport = null; jalview.datamodel.AlignmentI jal = null; jalview.datamodel.CigarArray view = null; for (int pe = 0; pe < tp.getEntryCount(); pe++) @@ -604,7 +604,7 @@ public class Tree extends DatastoreItem return null; } - private AlignViewport getViewport(Vobject v_parent) + private AlignmentViewport getViewport(Vobject v_parent) { if (v_parent instanceof uk.ac.vamsas.objects.core.Alignment) { diff --git a/src/jalview/javascript/MouseOverListener.java b/src/jalview/javascript/MouseOverListener.java index d3d3d29..9d0279b 100644 --- a/src/jalview/javascript/MouseOverListener.java +++ b/src/jalview/javascript/MouseOverListener.java @@ -37,7 +37,9 @@ public class MouseOverListener extends JSFunctionExec implements int i = -1; - public void mouseOver(SequenceI seq, int index, VamsasSource source) + @Override + public void mouseOverSequence(SequenceI seq, int index, + VamsasSource source) { if (seq != last || i != index) { diff --git a/src/jalview/javascript/MouseOverStructureListener.java b/src/jalview/javascript/MouseOverStructureListener.java index 4db44e1..f46cd90 100644 --- a/src/jalview/javascript/MouseOverStructureListener.java +++ b/src/jalview/javascript/MouseOverStructureListener.java @@ -20,9 +20,6 @@ */ package jalview.javascript; -import java.awt.Color; -import java.util.ArrayList; - import jalview.api.AlignmentViewPanel; import jalview.api.FeatureRenderer; import jalview.api.SequenceRenderer; @@ -30,11 +27,15 @@ import jalview.appletgui.AlignFrame; import jalview.bin.JalviewLite; import jalview.datamodel.SequenceI; import jalview.ext.jmol.JmolCommands; +import jalview.structure.AtomSpec; import jalview.structure.StructureListener; import jalview.structure.StructureMapping; import jalview.structure.StructureMappingcommandSet; import jalview.structure.StructureSelectionManager; +import java.util.ArrayList; +import java.util.List; + /** * Propagate events involving PDB structures associated with sequences to a * javascript function. Generally, the javascript handler is called with a @@ -133,7 +134,6 @@ public class MouseOverStructureListener extends JSFunctionExec implements return modelSet; } - @Override public void mouseOverStructure(int atomIndex, String strInfo) { @@ -144,24 +144,27 @@ public class MouseOverStructureListener extends JSFunctionExec implements } @Override - public void highlightAtom(int atomIndex, int pdbResNum, String chain, - String pdbId) + public void highlightAtoms(List atoms) { - String[] st = new String[0]; - try - { - executeJavascriptFunction(_listenerfn, st = new String[] - { "mouseover", "" + pdbId, "" + chain, "" + (pdbResNum), - "" + atomIndex }); - } catch (Exception ex) + for (AtomSpec atom : atoms) { - System.err.println("Couldn't execute callback with " + _listenerfn - + " using args { " + st[0] + ", " + st[1] + ", " + st[2] - + "," + st[3] + "\n"); - ex.printStackTrace(); - + try + { + // TODO is this right? StructureSelectionManager passes pdbFile as the + // field that is interpreted (in 2.8.2) as pdbId? + // JBPComment: yep - this is right! the Javascript harness uses the + // absolute pdbFile URI to locate the PDB file in the external viewer + executeJavascriptFunction(_listenerfn, new String[] + { "mouseover", "" + atom.getPdbFile(), + "" + atom.getChain(), + "" + (atom.getPdbResNum()), "" + atom.getAtomIndex() }); + } catch (Exception ex) + { + System.err.println("Couldn't execute callback with " + _listenerfn + + " for atomSpec: " + atom); + ex.printStackTrace(); + } } - } @Override @@ -283,13 +286,6 @@ public class MouseOverStructureListener extends JSFunctionExec implements } @Override - public Color getColour(int atomIndex, int pdbResNum, String chain, - String pdbId) - { - return null; - } - - @Override public AlignFrame getAlignFrame() { // associated with all alignframes, always. diff --git a/src/jalview/jbgui/GAlignFrame.java b/src/jalview/jbgui/GAlignFrame.java index 78aaca6..befa3b1 100755 --- a/src/jalview/jbgui/GAlignFrame.java +++ b/src/jalview/jbgui/GAlignFrame.java @@ -20,13 +20,6 @@ */ package jalview.jbgui; -import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; -import jalview.bin.Cache; -import jalview.gui.JvSwingUtils; -import jalview.gui.Preferences; -import jalview.schemes.ColourSchemeProperty; -import jalview.util.MessageManager; - import java.awt.BorderLayout; import java.awt.Color; import java.awt.GridLayout; @@ -35,8 +28,11 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; +import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.HashMap; +import java.util.Map; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; @@ -50,77 +46,40 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButtonMenuItem; import javax.swing.JTabbedPane; +import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; +import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; +import jalview.api.SplitContainerI; +import jalview.bin.Cache; +import jalview.gui.JvSwingUtils; +import jalview.gui.Preferences; +import jalview.schemes.ColourSchemeProperty; +import jalview.util.MessageManager; + public class GAlignFrame extends JInternalFrame { protected JMenuBar alignFrameMenuBar = new JMenuBar(); - protected JMenu fileMenu = new JMenu(); - protected JMenuItem closeMenuItem = new JMenuItem(); - protected JMenu editMenu = new JMenu(); - - protected JMenu viewMenu = new JMenu(); - - protected JMenu annotationsMenu = new JMenu(); - protected JMenu colourMenu = new JMenu(); - protected JMenu calculateMenu = new JMenu(); - protected JMenu webService = new JMenu(); protected JMenuItem webServiceNoServices; - protected JMenuItem selectAllSequenceMenuItem = new JMenuItem(); - - protected JMenuItem deselectAllSequenceMenuItem = new JMenuItem(); - - protected JMenuItem invertSequenceMenuItem = new JMenuItem(); - - protected JMenuItem remove2LeftMenuItem = new JMenuItem(); - - protected JMenuItem remove2RightMenuItem = new JMenuItem(); - - protected JMenuItem removeGappedColumnMenuItem = new JMenuItem(); - - protected JMenuItem removeAllGapsMenuItem = new JMenuItem(); - public JCheckBoxMenuItem viewBoxesMenuItem = new JCheckBoxMenuItem(); public JCheckBoxMenuItem viewTextMenuItem = new JCheckBoxMenuItem(); - protected JMenuItem sortPairwiseMenuItem = new JMenuItem(); - - protected JMenuItem sortIDMenuItem = new JMenuItem(); - - protected JMenuItem sortLengthMenuItem = new JMenuItem(); - - protected JMenuItem sortGroupMenuItem = new JMenuItem(); - protected JMenu sortByAnnotScore = new JMenu(); - protected JMenuItem removeRedundancyMenuItem = new JMenuItem(); - - protected JMenuItem pairwiseAlignmentMenuItem = new JMenuItem(); - - protected JMenuItem PCAMenuItem = new JMenuItem(); - - protected JMenuItem averageDistanceTreeMenuItem = new JMenuItem(); - - protected JMenuItem neighbourTreeMenuItem = new JMenuItem(); - - BorderLayout borderLayout1 = new BorderLayout(); - public JLabel statusBar = new JLabel(); - protected JMenuItem saveAs = new JMenuItem(); - protected JMenu outputTextboxMenu = new JMenu(); protected JRadioButtonMenuItem clustalColour = new JRadioButtonMenuItem(); @@ -156,20 +115,12 @@ public class GAlignFrame extends JInternalFrame protected JRadioButtonMenuItem tcoffeeColour = new JRadioButtonMenuItem(); - JMenuItem njTreeBlosumMenuItem = new JMenuItem(); - - JMenuItem avDistanceTreeBlosumMenuItem = new JMenuItem(); - public JCheckBoxMenuItem annotationPanelMenuItem = new JCheckBoxMenuItem(); public JCheckBoxMenuItem colourTextMenuItem = new JCheckBoxMenuItem(); public JCheckBoxMenuItem showNonconservedMenuItem = new JCheckBoxMenuItem(); - JMenuItem htmlMenuItem = new JMenuItem(); - - JMenuItem overviewMenuItem = new JMenuItem(); - protected JMenuItem undoMenuItem = new JMenuItem(); protected JMenuItem redoMenuItem = new JMenuItem(); @@ -180,60 +131,30 @@ public class GAlignFrame extends JInternalFrame public JCheckBoxMenuItem wrapMenuItem = new JCheckBoxMenuItem(); - JMenuItem printMenuItem = new JMenuItem(); - public JCheckBoxMenuItem renderGapsMenuItem = new JCheckBoxMenuItem(); - JMenuItem findMenuItem = new JMenuItem(); - public JCheckBoxMenuItem abovePIDThreshold = new JCheckBoxMenuItem(); public JCheckBoxMenuItem showSeqFeatures = new JCheckBoxMenuItem(); public JCheckBoxMenuItem showSeqFeaturesHeight = new JCheckBoxMenuItem(); - JMenuItem deleteGroups = new JMenuItem(); - - JMenuItem createGroup = new JMenuItem(); - - JMenuItem unGroup = new JMenuItem(); - - JMenuItem delete = new JMenuItem(); - JMenuItem copy = new JMenuItem(); JMenuItem cut = new JMenuItem(); JMenu pasteMenu = new JMenu(); - JMenuItem pasteNew = new JMenuItem(); - - JMenuItem pasteThis = new JMenuItem(); - public JCheckBoxMenuItem applyToAllGroups = new JCheckBoxMenuItem(); - JMenuItem createPNG = new JMenuItem(); - - JMenuItem createBioJS = new JMenuItem(); - - JMenuItem createSVG = new JMenuItem(); - - protected JMenuItem font = new JMenuItem(); - public JCheckBoxMenuItem seqLimits = new JCheckBoxMenuItem(); - JMenuItem epsFile = new JMenuItem(); - - JMenuItem LoadtreeMenuItem = new JMenuItem(); - public JCheckBoxMenuItem scaleAbove = new JCheckBoxMenuItem(); public JCheckBoxMenuItem scaleLeft = new JCheckBoxMenuItem(); public JCheckBoxMenuItem scaleRight = new JCheckBoxMenuItem(); - protected JMenuItem modifyPID = new JMenuItem(); - protected JMenuItem modifyConservation = new JMenuItem(); protected JMenu sortByTreeMenu = new JMenu(); @@ -242,8 +163,6 @@ public class GAlignFrame extends JInternalFrame protected JMenu calculateTree = new JMenu(); - JMenu jMenu2 = new JMenu(); - protected JCheckBoxMenuItem padGapsMenuitem = new JCheckBoxMenuItem(); protected JCheckBoxMenuItem showNpFeatsMenuitem = new JCheckBoxMenuItem(); @@ -252,68 +171,20 @@ public class GAlignFrame extends JInternalFrame protected ButtonGroup colours = new ButtonGroup(); - JMenuItem vamsasStore = new JMenuItem(); - protected JMenuItem showTranslation = new JMenuItem(); - protected JMenuItem extractScores = new JMenuItem(); - - protected JMenuItem expandAlignment = new JMenuItem(); - protected JMenu showProducts = new JMenu(); - public JMenuItem openFeatureSettings = new JMenuItem(); - - JMenuItem fetchSequence = new JMenuItem(); - - JMenuItem annotationColour = new JMenuItem(); - - JMenuItem annotationColumn = new JMenuItem(); - protected JMenuItem rnahelicesColour = new JMenuItem(); - JMenuItem associatedData = new JMenuItem(); - protected JCheckBoxMenuItem autoCalculate = new JCheckBoxMenuItem(); protected JCheckBoxMenuItem sortByTree = new JCheckBoxMenuItem(); protected JCheckBoxMenuItem listenToViewSelections = new JCheckBoxMenuItem(); - JMenu addSequenceMenu = new JMenu(); - - JMenuItem addFromFile = new JMenuItem(); - - JMenuItem addFromText = new JMenuItem(); - - JMenuItem addFromURL = new JMenuItem(); - - JMenuItem exportAnnotations = new JMenuItem(); - - JMenuItem exportFeatures = new JMenuItem(); - protected JPanel statusPanel = new JPanel(); - GridLayout gridLayout1 = new GridLayout(); - - JMenu jMenu3 = new JMenu(); - - JMenuItem showAllSeqs = new JMenuItem(); - - JMenuItem showAllColumns = new JMenuItem(); - - JMenu hideMenu = new JMenu(); - - JMenuItem hideSelSequences = new JMenuItem(); - - JMenuItem hideSelColumns = new JMenuItem(); - - JMenuItem hideAllButSelection = new JMenuItem(); - - JMenuItem hideAllSelection = new JMenuItem(); - - JMenuItem showAllhidden = new JMenuItem(); - protected JMenuItem showAllSeqAnnotations = new JMenuItem(); protected JMenuItem hideAllSeqAnnotations = new JMenuItem(); @@ -322,27 +193,15 @@ public class GAlignFrame extends JInternalFrame protected JMenuItem hideAllAlAnnotations = new JMenuItem(); - protected JCheckBoxMenuItem sortAnnBySequence = new JCheckBoxMenuItem(); - - protected JCheckBoxMenuItem sortAnnByLabel = new JCheckBoxMenuItem(); + protected JCheckBoxMenuItem showComplementMenuItem = new JCheckBoxMenuItem(); protected JCheckBoxMenuItem hiddenMarkers = new JCheckBoxMenuItem(); - JMenuItem invertColSel = new JMenuItem(); - protected JTabbedPane tabbedPane = new JTabbedPane(); - JMenuItem save = new JMenuItem(); - protected JMenuItem reload = new JMenuItem(); - JMenuItem newView = new JMenuItem(); - - JMenuItem textColour = new JMenuItem(); - - JMenu formatMenu = new JMenu(); - - JMenu selectMenu = new JMenu(); + protected JMenu formatMenu = new JMenu(); protected JCheckBoxMenuItem idRightAlign = new JCheckBoxMenuItem(); @@ -354,18 +213,6 @@ public class GAlignFrame extends JInternalFrame protected JMenuItem expandViews = new JMenuItem(); - JMenuItem pageSetup = new JMenuItem(); - - JMenuItem alignmentProperties = new JMenuItem(); - - JMenu tooltipSettingsMenu = new JMenu(); - - private JMenuItem justifyLeftMenuItem = new JMenuItem(); - - private JMenuItem justifyRightMenuItem = new JMenuItem(); - - JMenu autoAnnMenu = new JMenu(); - protected JCheckBoxMenuItem showGroupConsensus = new JCheckBoxMenuItem(); protected JCheckBoxMenuItem showGroupConservation = new JCheckBoxMenuItem(); @@ -378,16 +225,14 @@ public class GAlignFrame extends JInternalFrame protected JCheckBoxMenuItem applyAutoAnnotationSettings = new JCheckBoxMenuItem(); - protected JRadioButtonMenuItem showAutoFirst = new JRadioButtonMenuItem(); - - protected JRadioButtonMenuItem showAutoLast = new JRadioButtonMenuItem(); - - private JMenuItem grpsFromSelection = new JMenuItem(); - private SequenceAnnotationOrder annotationSortOrder; private boolean showAutoCalculatedAbove = false; + private Map accelerators = new HashMap(); + + private SplitContainerI splitFrame; + public GAlignFrame() { try @@ -401,7 +246,7 @@ public class GAlignFrame extends JInternalFrame JMenuItem item = new JMenuItem( jalview.io.FormatAdapter.WRITEABLE_FORMATS[i]); - item.addActionListener(new java.awt.event.ActionListener() + item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -505,9 +350,8 @@ public class GAlignFrame extends JInternalFrame // colours.add(covariationColour); colours.add(tcoffeeColour); colours.add(RNAInteractionColour); - setColourSelected(jalview.bin.Cache - .getDefault("DEFAULT_COLOUR", "None")); - + setColourSelected(jalview.bin.Cache.getDefault( + Preferences.DEFAULT_COLOUR, "None")); } public void setColourSelected(String defaultColour) @@ -609,82 +453,88 @@ public class GAlignFrame extends JInternalFrame private void jbInit() throws Exception { - fileMenu.setText(MessageManager.getString("action.file")); - saveAs.setText(MessageManager.getString("action.save_as") + "..."); - saveAs.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_S, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask() - | java.awt.event.KeyEvent.SHIFT_MASK, false)); - saveAs.addActionListener(new ActionListener() + JMenuItem saveAs = new JMenuItem( + MessageManager.getString("action.save_as") + "..."); + ActionListener al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { saveAs_actionPerformed(e); } - }); + }; + KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask() + | KeyEvent.SHIFT_MASK, false); + addMenuActionAndAccelerator(keyStroke, saveAs, al); + closeMenuItem.setText(MessageManager.getString("action.close")); - closeMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_W, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - closeMenuItem.addActionListener(new java.awt.event.ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_W, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { closeMenuItem_actionPerformed(false); } - }); - editMenu.setText(MessageManager.getString("action.edit")); - viewMenu.setText(MessageManager.getString("action.view")); - annotationsMenu.setText(MessageManager.getString("action.annotations")); + }; + addMenuActionAndAccelerator(keyStroke, closeMenuItem, al); + + JMenu editMenu = new JMenu(MessageManager.getString("action.edit")); + JMenu viewMenu = new JMenu(MessageManager.getString("action.view")); + JMenu annotationsMenu = new JMenu( + MessageManager.getString("action.annotations")); + JMenu showMenu = new JMenu(MessageManager.getString("action.show")); colourMenu.setText(MessageManager.getString("action.colour")); - calculateMenu.setText(MessageManager.getString("action.calculate")); + JMenu calculateMenu = new JMenu( + MessageManager.getString("action.calculate")); webService.setText(MessageManager.getString("action.web_service")); - selectAllSequenceMenuItem.setText(MessageManager + JMenuItem selectAllSequenceMenuItem = new JMenuItem( + MessageManager .getString("action.select_all")); - selectAllSequenceMenuItem.setAccelerator(javax.swing.KeyStroke - .getKeyStroke(java.awt.event.KeyEvent.VK_A, Toolkit - .getDefaultToolkit().getMenuShortcutKeyMask(), false)); - selectAllSequenceMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - selectAllSequenceMenuItem_actionPerformed(e); - } - }); - deselectAllSequenceMenuItem.setText(MessageManager - .getString("action.deselect_all")); - deselectAllSequenceMenuItem.setAccelerator(javax.swing.KeyStroke - .getKeyStroke(java.awt.event.KeyEvent.VK_ESCAPE, 0, false)); - deselectAllSequenceMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - deselectAllSequenceMenuItem_actionPerformed(e); - } - }); - invertSequenceMenuItem.setText(MessageManager - .getString("action.invert_sequence_selection")); - invertSequenceMenuItem.setAccelerator(javax.swing.KeyStroke - .getKeyStroke(java.awt.event.KeyEvent.VK_I, Toolkit - .getDefaultToolkit().getMenuShortcutKeyMask(), false)); - invertSequenceMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - invertSequenceMenuItem_actionPerformed(e); - } - }); - grpsFromSelection.setText(MessageManager - .getString("action.make_groups_selection")); - grpsFromSelection.addActionListener(new java.awt.event.ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_A, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + selectAllSequenceMenuItem_actionPerformed(e); + } + }; + addMenuActionAndAccelerator(keyStroke, selectAllSequenceMenuItem, al); + + JMenuItem deselectAllSequenceMenuItem = new JMenuItem( + MessageManager.getString("action.deselect_all")); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + deselectAllSequenceMenuItem_actionPerformed(e); + } + }; + addMenuActionAndAccelerator(keyStroke, deselectAllSequenceMenuItem, al); + + JMenuItem invertSequenceMenuItem = new JMenuItem( + MessageManager.getString("action.invert_sequence_selection")); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_I, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + invertSequenceMenuItem_actionPerformed(e); + } + }; + addMenuActionAndAccelerator(keyStroke, invertSequenceMenuItem, al); + + JMenuItem grpsFromSelection = new JMenuItem( + MessageManager.getString("action.make_groups_selection")); + grpsFromSelection.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -692,11 +542,11 @@ public class GAlignFrame extends JInternalFrame makeGrpsFromSelection_actionPerformed(e); } }); - expandAlignment.setText(MessageManager - .getString("action.view_flanking_regions")); + JMenuItem expandAlignment = new JMenuItem( + MessageManager.getString("action.view_flanking_regions")); expandAlignment.setToolTipText(MessageManager .getString("label.view_flanking_regions")); - expandAlignment.addActionListener(new java.awt.event.ActionListener() + expandAlignment.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -704,88 +554,86 @@ public class GAlignFrame extends JInternalFrame expand_newalign(e); } }); - remove2LeftMenuItem.setText(MessageManager - .getString("action.remove_left")); - remove2LeftMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_L, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - remove2LeftMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - remove2LeftMenuItem_actionPerformed(e); - } - }); - remove2RightMenuItem.setText(MessageManager - .getString("action.remove_right")); - remove2RightMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_R, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - remove2RightMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - remove2RightMenuItem_actionPerformed(e); - } - }); - removeGappedColumnMenuItem.setText(MessageManager - .getString("action.remove_empty_columns")); - removeGappedColumnMenuItem.setAccelerator(javax.swing.KeyStroke - .getKeyStroke(java.awt.event.KeyEvent.VK_E, Toolkit - .getDefaultToolkit().getMenuShortcutKeyMask(), false)); - removeGappedColumnMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - removeGappedColumnMenuItem_actionPerformed(e); - } - }); - removeAllGapsMenuItem.setText(MessageManager - .getString("action.remove_all_gaps")); - removeAllGapsMenuItem.setAccelerator(javax.swing.KeyStroke - .getKeyStroke(java.awt.event.KeyEvent.VK_E, Toolkit - .getDefaultToolkit().getMenuShortcutKeyMask() - | java.awt.event.KeyEvent.SHIFT_MASK, false)); - removeAllGapsMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - removeAllGapsMenuItem_actionPerformed(e); - } - }); - justifyLeftMenuItem.setText(MessageManager - .getString("action.left_justify_alignment")); - justifyLeftMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - justifyLeftMenuItem_actionPerformed(e); - } - }); - justifyRightMenuItem.setText(MessageManager - .getString("action.right_justify_alignment")); - justifyRightMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - justifyRightMenuItem_actionPerformed(e); - } - }); + JMenuItem remove2LeftMenuItem = new JMenuItem( + MessageManager.getString("action.remove_left")); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_L, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + remove2LeftMenuItem_actionPerformed(e); + } + }; + addMenuActionAndAccelerator(keyStroke, remove2LeftMenuItem, al); + + JMenuItem remove2RightMenuItem = new JMenuItem( + MessageManager.getString("action.remove_right")); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_R, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + remove2RightMenuItem_actionPerformed(e); + } + }; + addMenuActionAndAccelerator(keyStroke, remove2RightMenuItem, al); + + JMenuItem removeGappedColumnMenuItem = new JMenuItem( + MessageManager.getString("action.remove_empty_columns")); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_E, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + removeGappedColumnMenuItem_actionPerformed(e); + } + }; + addMenuActionAndAccelerator(keyStroke, removeGappedColumnMenuItem, al); + + JMenuItem removeAllGapsMenuItem = new JMenuItem( + MessageManager.getString("action.remove_all_gaps")); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_E, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask() + | KeyEvent.SHIFT_MASK, false); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + removeAllGapsMenuItem_actionPerformed(e); + } + }; + addMenuActionAndAccelerator(keyStroke, removeAllGapsMenuItem, al); + + JMenuItem justifyLeftMenuItem = new JMenuItem( + MessageManager.getString("action.left_justify_alignment")); + justifyLeftMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + justifyLeftMenuItem_actionPerformed(e); + } + }); + JMenuItem justifyRightMenuItem = new JMenuItem( + MessageManager.getString("action.right_justify_alignment")); + justifyRightMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + justifyRightMenuItem_actionPerformed(e); + } + }); viewBoxesMenuItem.setText(MessageManager.getString("action.boxes")); viewBoxesMenuItem.setState(true); - viewBoxesMenuItem.addActionListener(new java.awt.event.ActionListener() + viewBoxesMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -795,7 +643,7 @@ public class GAlignFrame extends JInternalFrame }); viewTextMenuItem.setText(MessageManager.getString("action.text")); viewTextMenuItem.setState(true); - viewTextMenuItem.addActionListener(new java.awt.event.ActionListener() + viewTextMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -806,28 +654,27 @@ public class GAlignFrame extends JInternalFrame showNonconservedMenuItem.setText(MessageManager .getString("label.show_non_conversed")); showNonconservedMenuItem.setState(false); - showNonconservedMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - showUnconservedMenuItem_actionPerformed(e); - } - }); - sortPairwiseMenuItem.setText(MessageManager - .getString("action.by_pairwise_id")); - sortPairwiseMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - sortPairwiseMenuItem_actionPerformed(e); - } - }); - sortIDMenuItem.setText(MessageManager.getString("action.by_id")); - sortIDMenuItem.addActionListener(new java.awt.event.ActionListener() + showNonconservedMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + showUnconservedMenuItem_actionPerformed(e); + } + }); + JMenuItem sortPairwiseMenuItem = new JMenuItem( + MessageManager.getString("action.by_pairwise_id")); + sortPairwiseMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + sortPairwiseMenuItem_actionPerformed(e); + } + }); + JMenuItem sortIDMenuItem = new JMenuItem( + MessageManager.getString("action.by_id")); + sortIDMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -835,19 +682,19 @@ public class GAlignFrame extends JInternalFrame sortIDMenuItem_actionPerformed(e); } }); - sortLengthMenuItem - .setText(MessageManager.getString("action.by_length")); - sortLengthMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - sortLengthMenuItem_actionPerformed(e); - } - }); - sortGroupMenuItem.setText(MessageManager.getString("action.by_group")); - sortGroupMenuItem.addActionListener(new java.awt.event.ActionListener() + JMenuItem sortLengthMenuItem = new JMenuItem( + MessageManager.getString("action.by_length")); + sortLengthMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + sortLengthMenuItem_actionPerformed(e); + } + }); + JMenuItem sortGroupMenuItem = new JMenuItem( + MessageManager.getString("action.by_group")); + sortGroupMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -855,34 +702,34 @@ public class GAlignFrame extends JInternalFrame sortGroupMenuItem_actionPerformed(e); } }); - removeRedundancyMenuItem.setText(MessageManager + + JMenuItem removeRedundancyMenuItem = new JMenuItem(MessageManager .getString("action.remove_redundancy").concat("...")); - removeRedundancyMenuItem.setAccelerator(javax.swing.KeyStroke - .getKeyStroke(java.awt.event.KeyEvent.VK_D, Toolkit - .getDefaultToolkit().getMenuShortcutKeyMask(), false)); - removeRedundancyMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - removeRedundancyMenuItem_actionPerformed(e); - } - }); - pairwiseAlignmentMenuItem.setText(MessageManager - .getString("action.pairwise_alignment")); - pairwiseAlignmentMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - pairwiseAlignmentMenuItem_actionPerformed(e); - } - }); - PCAMenuItem.setText(MessageManager - .getString("label.principal_component_analysis")); - PCAMenuItem.addActionListener(new java.awt.event.ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_D, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + removeRedundancyMenuItem_actionPerformed(e); + } + }; + addMenuActionAndAccelerator(keyStroke, removeRedundancyMenuItem, al); + + JMenuItem pairwiseAlignmentMenuItem = new JMenuItem( + MessageManager.getString("action.pairwise_alignment")); + pairwiseAlignmentMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + pairwiseAlignmentMenuItem_actionPerformed(e); + } + }); + JMenuItem PCAMenuItem = new JMenuItem( + MessageManager.getString("label.principal_component_analysis")); + PCAMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -890,29 +737,28 @@ public class GAlignFrame extends JInternalFrame PCAMenuItem_actionPerformed(e); } }); - averageDistanceTreeMenuItem.setText(MessageManager - .getString("label.average_distance_identity")); - averageDistanceTreeMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - averageDistanceTreeMenuItem_actionPerformed(e); - } - }); - neighbourTreeMenuItem.setText(MessageManager - .getString("label.neighbour_joining_identity")); - neighbourTreeMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - neighbourTreeMenuItem_actionPerformed(e); - } - }); - this.getContentPane().setLayout(borderLayout1); + 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)); statusBar.setBackground(Color.white); statusBar.setFont(new java.awt.Font("Verdana", 0, 11)); @@ -921,8 +767,7 @@ public class GAlignFrame extends JInternalFrame outputTextboxMenu.setText(MessageManager .getString("label.out_to_textbox")); clustalColour.setText(MessageManager.getString("label.clustalx")); - - clustalColour.addActionListener(new java.awt.event.ActionListener() + clustalColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -931,7 +776,7 @@ public class GAlignFrame extends JInternalFrame } }); zappoColour.setText(MessageManager.getString("label.zappo")); - zappoColour.addActionListener(new java.awt.event.ActionListener() + zappoColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -940,7 +785,7 @@ public class GAlignFrame extends JInternalFrame } }); taylorColour.setText(MessageManager.getString("label.taylor")); - taylorColour.addActionListener(new java.awt.event.ActionListener() + taylorColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -950,17 +795,16 @@ public class GAlignFrame extends JInternalFrame }); hydrophobicityColour.setText(MessageManager .getString("label.hydrophobicity")); - hydrophobicityColour - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - hydrophobicityColour_actionPerformed(e); - } - }); + hydrophobicityColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + hydrophobicityColour_actionPerformed(e); + } + }); helixColour.setText(MessageManager.getString("label.helix_propensity")); - helixColour.addActionListener(new java.awt.event.ActionListener() + helixColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -970,7 +814,7 @@ public class GAlignFrame extends JInternalFrame }); strandColour.setText(MessageManager .getString("label.strand_propensity")); - strandColour.addActionListener(new java.awt.event.ActionListener() + strandColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -979,7 +823,7 @@ public class GAlignFrame extends JInternalFrame } }); turnColour.setText(MessageManager.getString("label.turn_propensity")); - turnColour.addActionListener(new java.awt.event.ActionListener() + turnColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -988,7 +832,7 @@ public class GAlignFrame extends JInternalFrame } }); buriedColour.setText(MessageManager.getString("label.buried_index")); - buriedColour.addActionListener(new java.awt.event.ActionListener() + buriedColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -998,7 +842,7 @@ public class GAlignFrame extends JInternalFrame }); userDefinedColour.setText(MessageManager .getString("action.user_defined")); - userDefinedColour.addActionListener(new java.awt.event.ActionListener() + userDefinedColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1008,7 +852,7 @@ public class GAlignFrame extends JInternalFrame }); PIDColour .setText(MessageManager.getString("label.percentage_identity")); - PIDColour.addActionListener(new java.awt.event.ActionListener() + PIDColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1018,7 +862,7 @@ public class GAlignFrame extends JInternalFrame }); BLOSUM62Colour .setText(MessageManager.getString("label.blosum62_score")); - BLOSUM62Colour.addActionListener(new java.awt.event.ActionListener() + BLOSUM62Colour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1027,7 +871,7 @@ public class GAlignFrame extends JInternalFrame } }); nucleotideColour.setText(MessageManager.getString("label.nucleotide")); - nucleotideColour.addActionListener(new java.awt.event.ActionListener() + nucleotideColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1038,55 +882,51 @@ public class GAlignFrame extends JInternalFrame purinePyrimidineColour.setText(MessageManager .getString("label.purine_pyrimidine")); - purinePyrimidineColour - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - purinePyrimidineColour_actionPerformed(e); - } - }); + purinePyrimidineColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + purinePyrimidineColour_actionPerformed(e); + } + }); RNAInteractionColour.setText("RNA Interaction type"); - RNAInteractionColour - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - RNAInteractionColour_actionPerformed(e); - } - }); + RNAInteractionColour.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + RNAInteractionColour_actionPerformed(e); + } + }); /* * covariationColour.setText("Covariation"); - * covariationColour.addActionListener(new java.awt.event.ActionListener() { - * public void actionPerformed(ActionEvent e) { - * covariationColour_actionPerformed(e); } }); + * covariationColour.addActionListener(new ActionListener() { public void + * actionPerformed(ActionEvent e) { covariationColour_actionPerformed(e); } + * }); */ - avDistanceTreeBlosumMenuItem.setText(MessageManager - .getString("label.average_distance_bloslum62")); - avDistanceTreeBlosumMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - avTreeBlosumMenuItem_actionPerformed(e); - } - }); - njTreeBlosumMenuItem.setText(MessageManager - .getString("label.neighbour_blosum62")); - njTreeBlosumMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - njTreeBlosumMenuItem_actionPerformed(e); - } - }); + JMenuItem avDistanceTreeBlosumMenuItem = new JMenuItem( + MessageManager.getString("label.average_distance_bloslum62")); + 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")); @@ -1149,8 +989,11 @@ public class GAlignFrame extends JInternalFrame SequenceAnnotationOrder sortAnnotationsBy = SequenceAnnotationOrder .valueOf(Cache.getDefault(Preferences.SORT_ANNOTATIONS, SequenceAnnotationOrder.NONE.name())); - sortAnnBySequence.setText(MessageManager - .getString("label.sort_annotations_by_sequence")); + final JCheckBoxMenuItem sortAnnBySequence = new JCheckBoxMenuItem( + MessageManager.getString("label.sort_annotations_by_sequence")); + final JCheckBoxMenuItem sortAnnByLabel = new JCheckBoxMenuItem( + MessageManager.getString("label.sort_annotations_by_label")); + sortAnnBySequence .setSelected(sortAnnotationsBy == SequenceAnnotationOrder.SEQUENCE_AND_LABEL); sortAnnBySequence.addActionListener(new ActionListener() @@ -1165,8 +1008,6 @@ public class GAlignFrame extends JInternalFrame sortAnnotations_actionPerformed(); } }); - sortAnnByLabel.setText(MessageManager - .getString("label.sort_annotations_by_label")); sortAnnByLabel .setSelected(sortAnnotationsBy == SequenceAnnotationOrder.LABEL_AND_SEQUENCE); sortAnnByLabel.addActionListener(new ActionListener() @@ -1183,17 +1024,18 @@ public class GAlignFrame extends JInternalFrame }); colourTextMenuItem.setText(MessageManager .getString("label.colour_text")); - colourTextMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - colourTextMenuItem_actionPerformed(e); - } - }); - htmlMenuItem.setText(MessageManager.getString("label.html")); - htmlMenuItem.addActionListener(new java.awt.event.ActionListener() + colourTextMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + colourTextMenuItem_actionPerformed(e); + } + }); + + JMenuItem htmlMenuItem = new JMenuItem( + MessageManager.getString("label.html")); + htmlMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1202,9 +1044,8 @@ public class GAlignFrame extends JInternalFrame } }); - // TODO uncomment when supported by MassageManager - // createBioJS.setText(MessageManager.getString("label.biojs_html_export")); - createBioJS.setText("BioJS"); + JMenuItem createBioJS = new JMenuItem( + MessageManager.getString("label.biojs_html_export")); createBioJS.addActionListener(new java.awt.event.ActionListener() { @Override @@ -1214,9 +1055,9 @@ public class GAlignFrame extends JInternalFrame } }); - overviewMenuItem.setText(MessageManager - .getString("label.overview_window")); - overviewMenuItem.addActionListener(new java.awt.event.ActionListener() + JMenuItem overviewMenuItem = new JMenuItem( + MessageManager.getString("label.overview_window")); + overviewMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1224,45 +1065,47 @@ public class GAlignFrame extends JInternalFrame overviewMenuItem_actionPerformed(e); } }); + undoMenuItem.setEnabled(false); undoMenuItem.setText(MessageManager.getString("action.undo")); - undoMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_Z, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - undoMenuItem.addActionListener(new java.awt.event.ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { undoMenuItem_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, undoMenuItem, al); + redoMenuItem.setEnabled(false); redoMenuItem.setText(MessageManager.getString("action.redo")); - redoMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_Y, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - redoMenuItem.addActionListener(new java.awt.event.ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_Y, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { redoMenuItem_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, redoMenuItem, al); + conservationMenuItem.setText(MessageManager .getString("action.by_conservation")); - conservationMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - conservationMenuItem_actionPerformed(e); - } - }); + conservationMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + conservationMenuItem_actionPerformed(e); + } + }); noColourmenuItem.setText(MessageManager.getString("label.none")); - noColourmenuItem.addActionListener(new java.awt.event.ActionListener() + noColourmenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1271,7 +1114,7 @@ public class GAlignFrame extends JInternalFrame } }); wrapMenuItem.setText(MessageManager.getString("label.wrap")); - wrapMenuItem.addActionListener(new java.awt.event.ActionListener() + wrapMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1279,47 +1122,52 @@ public class GAlignFrame extends JInternalFrame wrapMenuItem_actionPerformed(e); } }); - printMenuItem.setText(MessageManager.getString("action.print") + "..."); - printMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_P, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - printMenuItem.addActionListener(new java.awt.event.ActionListener() + + JMenuItem printMenuItem = new JMenuItem( + MessageManager.getString("action.print") + "..."); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_P, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { printMenuItem_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, printMenuItem, al); + renderGapsMenuItem .setText(MessageManager.getString("action.show_gaps")); renderGapsMenuItem.setState(true); - renderGapsMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - renderGapsMenuItem_actionPerformed(e); - } - }); - findMenuItem.setText(MessageManager.getString("action.find")); - findMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_F, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); + renderGapsMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + renderGapsMenuItem_actionPerformed(e); + } + }); + + JMenuItem findMenuItem = new JMenuItem( + MessageManager.getString("action.find")); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_F, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); findMenuItem.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.getString("label.find_tip"))); - findMenuItem.addActionListener(new java.awt.event.ActionListener() + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { findMenuItem_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, findMenuItem, al); + abovePIDThreshold.setText(MessageManager .getString("label.above_identity_threshold")); - abovePIDThreshold.addActionListener(new java.awt.event.ActionListener() + abovePIDThreshold.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1442,12 +1290,14 @@ public class GAlignFrame extends JInternalFrame }); ButtonGroup buttonGroup = new ButtonGroup(); + final JRadioButtonMenuItem showAutoFirst = new JRadioButtonMenuItem( + MessageManager.getString("label.show_first")); + final JRadioButtonMenuItem showAutoLast = new JRadioButtonMenuItem( + MessageManager.getString("label.show_last")); buttonGroup.add(showAutoFirst); buttonGroup.add(showAutoLast); - showAutoFirst.setText(MessageManager.getString("label.show_first")); showAutoFirst.setSelected(Cache.getDefault( - Preferences.SHOW_AUTOCALC_ABOVE, - false)); + Preferences.SHOW_AUTOCALC_ABOVE, false)); showAutoFirst.addActionListener(new ActionListener() { @Override @@ -1457,7 +1307,6 @@ public class GAlignFrame extends JInternalFrame sortAnnotations_actionPerformed(); } }); - showAutoLast.setText(MessageManager.getString("label.show_last")); showAutoLast.setSelected(!showAutoFirst.isSelected()); showAutoLast.addActionListener(new ActionListener() { @@ -1470,7 +1319,7 @@ public class GAlignFrame extends JInternalFrame }); nucleotideColour.setText(MessageManager.getString("label.nucleotide")); - nucleotideColour.addActionListener(new java.awt.event.ActionListener() + nucleotideColour.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1491,71 +1340,79 @@ public class GAlignFrame extends JInternalFrame } }); - deleteGroups - .setText(MessageManager.getString("action.undefine_groups")); - deleteGroups.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_U, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - deleteGroups.addActionListener(new java.awt.event.ActionListener() + JMenuItem deleteGroups = new JMenuItem( + MessageManager.getString("action.undefine_groups")); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_U, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { deleteGroups_actionPerformed(e); } - }); - createGroup.setText(MessageManager.getString("action.create_groups")); - createGroup.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_G, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - createGroup.addActionListener(new java.awt.event.ActionListener() + }; + addMenuActionAndAccelerator(keyStroke, deleteGroups, al); + + JMenuItem createGroup = new JMenuItem( + MessageManager.getString("action.create_groups")); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { createGroup_actionPerformed(e); } - }); - unGroup.setText(MessageManager.getString("action.remove_group")); - unGroup.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_G, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask() - | java.awt.event.KeyEvent.SHIFT_MASK, false)); - unGroup.addActionListener(new java.awt.event.ActionListener() + }; + addMenuActionAndAccelerator(keyStroke, createGroup, al); + + JMenuItem unGroup = new JMenuItem( + MessageManager.getString("action.remove_group")); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask() + | KeyEvent.SHIFT_MASK, false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { unGroup_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, unGroup, al); + copy.setText(MessageManager.getString("action.copy")); - copy.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_C, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); - copy.addActionListener(new java.awt.event.ActionListener() + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { copy_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, copy, al); + cut.setText(MessageManager.getString("action.cut")); - cut.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_X, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - cut.addActionListener(new java.awt.event.ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { cut_actionPerformed(e); } - }); - delete.setText(MessageManager.getString("action.delete")); - delete.addActionListener(new java.awt.event.ActionListener() + }; + addMenuActionAndAccelerator(keyStroke, cut, al); + + JMenuItem delete = new JMenuItem( + MessageManager.getString("action.delete")); + delete.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1563,35 +1420,40 @@ public class GAlignFrame extends JInternalFrame delete_actionPerformed(e); } }); + pasteMenu.setText(MessageManager.getString("action.paste")); - pasteNew.setText(MessageManager.getString("label.to_new_alignment")); - pasteNew.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_V, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask() - | java.awt.event.KeyEvent.SHIFT_MASK, false)); - pasteNew.addActionListener(new java.awt.event.ActionListener() + JMenuItem pasteNew = new JMenuItem( + MessageManager.getString("label.to_new_alignment")); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask() + | KeyEvent.SHIFT_MASK, false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { pasteNew_actionPerformed(e); } - }); - pasteThis.setText(MessageManager.getString("label.to_this_alignment")); - pasteThis.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_V, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - pasteThis.addActionListener(new java.awt.event.ActionListener() + }; + addMenuActionAndAccelerator(keyStroke, pasteNew, al); + + JMenuItem pasteThis = new JMenuItem( + MessageManager.getString("label.to_this_alignment")); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { pasteThis_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, pasteThis, al); + applyToAllGroups.setText(MessageManager .getString("label.apply_colour_to_all_groups")); - applyToAllGroups.addActionListener(new java.awt.event.ActionListener() + applyToAllGroups.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1599,7 +1461,8 @@ public class GAlignFrame extends JInternalFrame applyToAllGroups_actionPerformed(e); } }); - createPNG.addActionListener(new java.awt.event.ActionListener() + JMenuItem createPNG = new JMenuItem("PNG"); + createPNG.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1609,10 +1472,9 @@ public class GAlignFrame extends JInternalFrame }); createPNG.setActionCommand(MessageManager .getString("label.save_png_image")); - createPNG.setText("PNG"); - font.setText(MessageManager.getString("action.font")); - font.addActionListener(new java.awt.event.ActionListener() + JMenuItem font = new JMenuItem(MessageManager.getString("action.font")); + font.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1623,7 +1485,7 @@ public class GAlignFrame extends JInternalFrame seqLimits.setText(MessageManager .getString("label.show_sequence_limits")); seqLimits.setState(jalview.bin.Cache.getDefault("SHOW_JVSUFFIX", true)); - seqLimits.addActionListener(new java.awt.event.ActionListener() + seqLimits.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1631,8 +1493,8 @@ public class GAlignFrame extends JInternalFrame seqLimit_actionPerformed(e); } }); - epsFile.setText("EPS"); - epsFile.addActionListener(new java.awt.event.ActionListener() + JMenuItem epsFile = new JMenuItem("EPS"); + epsFile.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1641,8 +1503,8 @@ public class GAlignFrame extends JInternalFrame } }); - createSVG.setText("SVG"); - createSVG.addActionListener(new java.awt.event.ActionListener() + JMenuItem createSVG = new JMenuItem("SVG"); + createSVG.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1651,22 +1513,22 @@ public class GAlignFrame extends JInternalFrame } }); - LoadtreeMenuItem.setActionCommand(MessageManager + JMenuItem loadTreeMenuItem = new JMenuItem( + MessageManager.getString("label.load_associated_tree")); + loadTreeMenuItem.setActionCommand(MessageManager .getString("label.load_tree_for_sequence_set")); - LoadtreeMenuItem.setText(MessageManager - .getString("label.load_associated_tree")); - LoadtreeMenuItem.addActionListener(new java.awt.event.ActionListener() + loadTreeMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - LoadtreeMenuItem_actionPerformed(e); + loadTreeMenuItem_actionPerformed(e); } }); scaleAbove.setVisible(false); scaleAbove.setText(MessageManager.getString("action.scale_above")); - scaleAbove.addActionListener(new java.awt.event.ActionListener() + scaleAbove.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1677,7 +1539,7 @@ public class GAlignFrame extends JInternalFrame scaleLeft.setVisible(false); scaleLeft.setSelected(true); scaleLeft.setText(MessageManager.getString("action.scale_left")); - scaleLeft.addActionListener(new java.awt.event.ActionListener() + scaleLeft.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1688,7 +1550,7 @@ public class GAlignFrame extends JInternalFrame scaleRight.setVisible(false); scaleRight.setSelected(true); scaleRight.setText(MessageManager.getString("action.scale_right")); - scaleRight.addActionListener(new java.awt.event.ActionListener() + scaleRight.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1700,15 +1562,14 @@ public class GAlignFrame extends JInternalFrame centreColumnLabelsMenuItem.setState(false); centreColumnLabelsMenuItem.setText(MessageManager .getString("label.centre_column_labels")); - centreColumnLabelsMenuItem - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - centreColumnLabels_actionPerformed(e); - } - }); + centreColumnLabelsMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + centreColumnLabels_actionPerformed(e); + } + }); followHighlightMenuItem.setVisible(true); followHighlightMenuItem.setState(true); followHighlightMenuItem.setText(MessageManager @@ -1724,9 +1585,9 @@ public class GAlignFrame extends JInternalFrame }); - modifyPID.setText(MessageManager - .getString("label.modify_identity_thereshold")); - modifyPID.addActionListener(new java.awt.event.ActionListener() + JMenuItem modifyPID = new JMenuItem( + MessageManager.getString("label.modify_identity_thereshold")); + modifyPID.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -1736,15 +1597,14 @@ public class GAlignFrame extends JInternalFrame }); modifyConservation.setText(MessageManager .getString("label.modify_conservation_thereshold")); - modifyConservation - .addActionListener(new java.awt.event.ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - modifyConservation_actionPerformed(e); - } - }); + modifyConservation.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + modifyConservation_actionPerformed(e); + } + }); sortByTreeMenu .setText(MessageManager.getString("action.by_tree_order")); sort.setText(MessageManager.getString("action.sort")); @@ -1793,7 +1653,6 @@ public class GAlignFrame extends JInternalFrame calculateTree .setText(MessageManager.getString("action.calculate_tree")); - jMenu2.setText(MessageManager.getString("label.export_image")); padGapsMenuitem.setText(MessageManager.getString("label.pad_gaps")); padGapsMenuitem.setState(jalview.bin.Cache .getDefault("PAD_GAPS", false)); @@ -1805,8 +1664,9 @@ public class GAlignFrame extends JInternalFrame padGapsMenuitem_actionPerformed(e); } }); + JMenuItem vamsasStore = new JMenuItem( + MessageManager.getString("label.vamsas_store")); vamsasStore.setVisible(false); - vamsasStore.setText(MessageManager.getString("label.vamsas_store")); vamsasStore.addActionListener(new ActionListener() { @Override @@ -1825,8 +1685,9 @@ public class GAlignFrame extends JInternalFrame showTranslation_actionPerformed(e); } }); - extractScores.setText(MessageManager.getString("label.extract_scores") - + "..."); + + JMenuItem extractScores = new JMenuItem( + MessageManager.getString("label.extract_scores") + "..."); extractScores.addActionListener(new ActionListener() { @Override @@ -1835,17 +1696,14 @@ public class GAlignFrame extends JInternalFrame extractScores_actionPerformed(e); } }); - extractScores.setVisible(true); // JBPNote: TODO: make gui for regex based - // score extraction + extractScores.setVisible(true); + // JBPNote: TODO: make gui for regex based score extraction + + // for show products actions see AlignFrame.canShowProducts showProducts.setText(MessageManager.getString("label.get_cross_refs")); - /* - * showProducts.addActionListener(new ActionListener() { - * - * public void actionPerformed(ActionEvent e) { - * showProducts_actionPerformed(e); } }); - */ - openFeatureSettings.setText(MessageManager - .getString("label.feature_settings")); + + JMenuItem openFeatureSettings = new JMenuItem( + MessageManager.getString("label.feature_settings")); openFeatureSettings.addActionListener(new ActionListener() { @Override @@ -1854,8 +1712,8 @@ public class GAlignFrame extends JInternalFrame featureSettings_actionPerformed(e); } }); - fetchSequence - .setText(MessageManager.getString("label.fetch_sequences")); + JMenuItem fetchSequence = new JMenuItem( + MessageManager.getString("label.fetch_sequences")); fetchSequence.addActionListener(new ActionListener() { @Override @@ -1865,8 +1723,8 @@ public class GAlignFrame extends JInternalFrame } }); - annotationColour.setText(MessageManager - .getString("action.by_annotation")); + JMenuItem annotationColour = new JMenuItem( + MessageManager.getString("action.by_annotation")); annotationColour.addActionListener(new ActionListener() { @Override @@ -1876,8 +1734,8 @@ public class GAlignFrame extends JInternalFrame } }); - annotationColumn.setText(MessageManager - .getString("action.select_by_annotation")); + JMenuItem annotationColumn = new JMenuItem( + MessageManager.getString("action.select_by_annotation")); annotationColumn.addActionListener(new ActionListener() { @Override @@ -1898,8 +1756,8 @@ public class GAlignFrame extends JInternalFrame } }); - associatedData.setText(MessageManager - .getString("label.load_features_annotations")); + JMenuItem associatedData = new JMenuItem( + MessageManager.getString("label.load_features_annotations")); associatedData.addActionListener(new ActionListener() { @Override @@ -1953,9 +1811,10 @@ public class GAlignFrame extends JInternalFrame } }); - addSequenceMenu - .setText(MessageManager.getString("label.add_sequences")); - addFromFile.setText(MessageManager.getString("label.from_file")); + JMenu addSequenceMenu = new JMenu( + MessageManager.getString("label.add_sequences")); + JMenuItem addFromFile = new JMenuItem( + MessageManager.getString("label.from_file")); addFromFile.addActionListener(new ActionListener() { @Override @@ -1964,7 +1823,8 @@ public class GAlignFrame extends JInternalFrame addFromFile_actionPerformed(e); } }); - addFromText.setText(MessageManager.getString("label.from_textbox")); + JMenuItem addFromText = new JMenuItem( + MessageManager.getString("label.from_textbox")); addFromText.addActionListener(new ActionListener() { @Override @@ -1973,7 +1833,8 @@ public class GAlignFrame extends JInternalFrame addFromText_actionPerformed(e); } }); - addFromURL.setText(MessageManager.getString("label.from_url")); + JMenuItem addFromURL = new JMenuItem( + MessageManager.getString("label.from_url")); addFromURL.addActionListener(new ActionListener() { @Override @@ -1982,8 +1843,8 @@ public class GAlignFrame extends JInternalFrame addFromURL_actionPerformed(e); } }); - exportFeatures.setText(MessageManager - .getString("label.export_features")); + JMenuItem exportFeatures = new JMenuItem( + MessageManager.getString("label.export_features")); exportFeatures.addActionListener(new ActionListener() { @Override @@ -1992,8 +1853,8 @@ public class GAlignFrame extends JInternalFrame exportFeatures_actionPerformed(e); } }); - exportAnnotations.setText(MessageManager - .getString("label.export_annotations")); + JMenuItem exportAnnotations = new JMenuItem( + MessageManager.getString("label.export_annotations")); exportAnnotations.addActionListener(new ActionListener() { @Override @@ -2002,9 +1863,9 @@ public class GAlignFrame extends JInternalFrame exportAnnotations_actionPerformed(e); } }); - statusPanel.setLayout(gridLayout1); - jMenu3.setText(MessageManager.getString("action.show")); - showAllSeqs.setText(MessageManager.getString("label.all_sequences")); + statusPanel.setLayout(new GridLayout()); + JMenuItem showAllSeqs = new JMenuItem( + MessageManager.getString("label.all_sequences")); showAllSeqs.setToolTipText(MessageManager .getString("label.toggle_sequence_visibility")); showAllSeqs.addActionListener(new ActionListener() @@ -2015,7 +1876,8 @@ public class GAlignFrame extends JInternalFrame showAllSeqs_actionPerformed(e); } }); - showAllColumns.setText(MessageManager.getString("label.all_columns")); + JMenuItem showAllColumns = new JMenuItem( + MessageManager.getString("label.all_columns")); showAllColumns.setToolTipText(MessageManager .getString("label.toggle_columns_visibility")); showAllColumns.addActionListener(new ActionListener() @@ -2026,9 +1888,9 @@ public class GAlignFrame extends JInternalFrame showAllColumns_actionPerformed(e); } }); - hideMenu.setText(MessageManager.getString("action.hide")); - hideSelSequences.setText(MessageManager - .getString("label.selected_sequences")); + JMenu hideMenu = new JMenu(MessageManager.getString("action.hide")); + JMenuItem hideSelSequences = new JMenuItem( + MessageManager.getString("label.selected_sequences")); hideSelSequences.setToolTipText(MessageManager .getString("label.toggle_sequence_visibility")); hideSelSequences.addActionListener(new ActionListener() @@ -2039,8 +1901,8 @@ public class GAlignFrame extends JInternalFrame hideSelSequences_actionPerformed(e); } }); - hideSelColumns.setText(MessageManager - .getString("label.selected_columns")); + JMenuItem hideSelColumns = new JMenuItem( + MessageManager.getString("label.selected_columns")); hideSelColumns.setToolTipText(MessageManager .getString("label.toggle_columns_visibility")); hideSelColumns.addActionListener(new ActionListener() @@ -2051,8 +1913,8 @@ public class GAlignFrame extends JInternalFrame hideSelColumns_actionPerformed(e); } }); - hideAllSelection.setText(MessageManager - .getString("label.selected_region")); + JMenuItem hideAllSelection = new JMenuItem( + MessageManager.getString("label.selected_region")); hideAllSelection.addActionListener(new ActionListener() { @Override @@ -2062,8 +1924,8 @@ public class GAlignFrame extends JInternalFrame } }); // TODO: should be hidden if no selection exists. - hideAllButSelection.setText(MessageManager - .getString("label.all_but_selected_region")); + JMenuItem hideAllButSelection = new JMenuItem( + MessageManager.getString("label.all_but_selected_region")); hideAllButSelection.addActionListener(new ActionListener() { @Override @@ -2072,8 +1934,8 @@ public class GAlignFrame extends JInternalFrame hideAllButSelection_actionPerformed(e); } }); - showAllhidden.setText(MessageManager - .getString("label.all_sequences_columns")); + JMenuItem showAllhidden = new JMenuItem( + MessageManager.getString("label.all_sequences_columns")); showAllhidden.setToolTipText(MessageManager .getString("label.toggles_visibility_hidden_selected_regions")); showAllhidden.addActionListener(new ActionListener() @@ -2094,20 +1956,32 @@ public class GAlignFrame extends JInternalFrame hiddenMarkers_actionPerformed(e); } }); - invertColSel.setText(MessageManager - .getString("action.invert_column_selection")); - invertColSel.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_I, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask() - | java.awt.event.KeyEvent.ALT_MASK, false)); - invertColSel.addActionListener(new ActionListener() + + JMenuItem invertColSel = new JMenuItem( + MessageManager.getString("action.invert_column_selection")); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_I, + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() + | KeyEvent.ALT_MASK, false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { invertColSel_actionPerformed(e); } + }; + addMenuActionAndAccelerator(keyStroke, invertColSel, al); + + showComplementMenuItem.setVisible(false); + showComplementMenuItem.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + showComplement_actionPerformed(showComplementMenuItem.getState()); + } }); + tabbedPane.addChangeListener(new javax.swing.event.ChangeListener() { @Override @@ -2134,18 +2008,20 @@ public class GAlignFrame extends JInternalFrame tabbedPane_focusGained(e); } }); - save.setText(MessageManager.getString("action.save")); - save.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_S, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - save.addActionListener(new ActionListener() + + JMenuItem save = new JMenuItem(MessageManager.getString("action.save")); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { save_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, save, al); + reload.setEnabled(false); reload.setText(MessageManager.getString("action.reload")); reload.addActionListener(new ActionListener() @@ -2156,23 +2032,26 @@ public class GAlignFrame extends JInternalFrame reload_actionPerformed(e); } }); - newView.setText(MessageManager.getString("action.new_view")); - newView.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_T, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask(), false)); - newView.addActionListener(new ActionListener() + + JMenuItem newView = new JMenuItem( + MessageManager.getString("action.new_view")); + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { newView_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, newView, al); + tabbedPane.setToolTipText("" + MessageManager.getString("label.rename_tab_eXpand_reGroup") + ""); - textColour.setText(MessageManager.getString("label.colour_text") - + "..."); + JMenuItem textColour = new JMenuItem( + MessageManager.getString("label.colour_text") + "..."); textColour.addActionListener(new ActionListener() { @Override @@ -2182,7 +2061,7 @@ public class GAlignFrame extends JInternalFrame } }); formatMenu.setText(MessageManager.getString("action.format")); - selectMenu.setText(MessageManager.getString("action.select")); + JMenu selectMenu = new JMenu(MessageManager.getString("action.select")); idRightAlign.setText(MessageManager .getString("label.right_align_sequence_id")); idRightAlign.addActionListener(new ActionListener() @@ -2193,32 +2072,35 @@ public class GAlignFrame extends JInternalFrame idRightAlign_actionPerformed(e); } }); + gatherViews.setEnabled(false); gatherViews.setText(MessageManager.getString("action.gather_views")); - gatherViews.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_G, 0, false)); - gatherViews.addActionListener(new ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_G, 0, false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { gatherViews_actionPerformed(e); } - }); + }; + addMenuActionAndAccelerator(keyStroke, gatherViews, al); + expandViews.setEnabled(false); expandViews.setText(MessageManager.getString("action.expand_views")); - expandViews.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - java.awt.event.KeyEvent.VK_X, 0, false)); - expandViews.addActionListener(new ActionListener() + keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_X, 0, false); + al = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { expandViews_actionPerformed(e); } - }); - pageSetup - .setText(MessageManager.getString("action.page_setup") + "..."); + }; + addMenuActionAndAccelerator(keyStroke, expandViews, al); + + JMenuItem pageSetup = new JMenuItem( + MessageManager.getString("action.page_setup") + "..."); pageSetup.addActionListener(new ActionListener() { @Override @@ -2227,8 +2109,8 @@ public class GAlignFrame extends JInternalFrame pageSetup_actionPerformed(e); } }); - alignmentProperties.setText(MessageManager - .getString("label.alignment_props") + "..."); + JMenuItem alignmentProperties = new JMenuItem( + MessageManager.getString("label.alignment_props") + "..."); alignmentProperties.addActionListener(new ActionListener() { @Override @@ -2237,10 +2119,14 @@ public class GAlignFrame extends JInternalFrame alignmentProperties(); } }); - tooltipSettingsMenu.setText(MessageManager - .getString("label.sequence_id_tooltip")); - autoAnnMenu.setText(MessageManager - .getString("label.autocalculated_annotation")); + JMenu tooltipSettingsMenu = new JMenu( + MessageManager.getString("label.sequence_id_tooltip")); + JMenu autoAnnMenu = new JMenu( + MessageManager.getString("label.autocalculated_annotation")); + + JMenu exportImageMenu = new JMenu( + MessageManager.getString("label.export_image")); + JMenu fileMenu = new JMenu(MessageManager.getString("action.file")); alignFrameMenuBar.add(fileMenu); alignFrameMenuBar.add(editMenu); alignFrameMenuBar.add(selectMenu); @@ -2261,10 +2147,10 @@ public class GAlignFrame extends JInternalFrame fileMenu.add(pageSetup); fileMenu.add(printMenuItem); fileMenu.addSeparator(); - fileMenu.add(jMenu2); + fileMenu.add(exportImageMenu); fileMenu.add(exportFeatures); fileMenu.add(exportAnnotations); - fileMenu.add(LoadtreeMenuItem); + fileMenu.add(loadTreeMenuItem); fileMenu.add(associatedData); fileMenu.addSeparator(); fileMenu.add(closeMenuItem); @@ -2287,14 +2173,28 @@ public class GAlignFrame extends JInternalFrame // editMenu.add(justifyRightMenuItem); // editMenu.addSeparator(); editMenu.add(padGapsMenuitem); + viewMenu.add(newView); viewMenu.add(expandViews); viewMenu.add(gatherViews); viewMenu.addSeparator(); - viewMenu.add(jMenu3); + viewMenu.add(showMenu); viewMenu.add(hideMenu); + viewMenu.add(showComplementMenuItem); viewMenu.addSeparator(); viewMenu.add(followHighlightMenuItem); + viewMenu.addSeparator(); + viewMenu.add(showSeqFeatures); + // viewMenu.add(showSeqFeaturesHeight); + viewMenu.add(openFeatureSettings); + tooltipSettingsMenu.add(showDbRefsMenuitem); + tooltipSettingsMenu.add(showNpFeatsMenuitem); + viewMenu.add(tooltipSettingsMenu); + viewMenu.addSeparator(); + viewMenu.add(alignmentProperties); + viewMenu.addSeparator(); + viewMenu.add(overviewMenuItem); + annotationsMenu.add(annotationPanelMenuItem); annotationsMenu.addSeparator(); annotationsMenu.add(showAllAlAnnotations); @@ -2316,18 +2216,7 @@ public class GAlignFrame extends JInternalFrame autoAnnMenu.add(showGroupConservation); autoAnnMenu.add(showGroupConsensus); annotationsMenu.add(autoAnnMenu); - viewMenu.addSeparator(); - viewMenu.add(showSeqFeatures); - // viewMenu.add(showSeqFeaturesHeight); - viewMenu.add(openFeatureSettings); - tooltipSettingsMenu.add(showDbRefsMenuitem); - tooltipSettingsMenu.add(showNpFeatsMenuitem); - viewMenu.add(tooltipSettingsMenu); - viewMenu.addSeparator(); - viewMenu.add(alignmentProperties); - viewMenu.addSeparator(); - viewMenu.add(overviewMenuItem); colourMenu.add(applyToAllGroups); colourMenu.add(textColour); colourMenu.addSeparator(); @@ -2377,20 +2266,20 @@ public class GAlignFrame extends JInternalFrame sort.add(sortGroupMenuItem); sort.add(sortPairwiseMenuItem); sort.add(sortByTreeMenu); - jMenu2.add(htmlMenuItem); - jMenu2.add(epsFile); - jMenu2.add(createPNG); - jMenu2.add(createBioJS); - jMenu2.add(createSVG); + exportImageMenu.add(htmlMenuItem); + exportImageMenu.add(epsFile); + exportImageMenu.add(createPNG); + exportImageMenu.add(createBioJS); + exportImageMenu.add(createSVG); addSequenceMenu.add(addFromFile); addSequenceMenu.add(addFromText); addSequenceMenu.add(addFromURL); this.getContentPane().add(statusPanel, java.awt.BorderLayout.SOUTH); statusPanel.add(statusBar, null); this.getContentPane().add(tabbedPane, java.awt.BorderLayout.CENTER); - jMenu3.add(showAllColumns); - jMenu3.add(showAllSeqs); - jMenu3.add(showAllhidden); + showMenu.add(showAllColumns); + showMenu.add(showAllSeqs); + showMenu.add(showAllhidden); hideMenu.add(hideSelColumns); hideMenu.add(hideSelSequences); hideMenu.add(hideAllSelection); @@ -2430,6 +2319,22 @@ public class GAlignFrame extends JInternalFrame } /** + * Adds the given action listener and key accelerator to the given menu item. + * Also saves in a lookup table to support lookup of action by key stroke. + * + * @param keyStroke + * @param menuItem + * @param actionListener + */ + protected void addMenuActionAndAccelerator(KeyStroke keyStroke, + JMenuItem menuItem, ActionListener actionListener) + { + menuItem.setAccelerator(keyStroke); + accelerators.put(keyStroke, menuItem); + menuItem.addActionListener(actionListener); + } + + /** * Action on clicking sort annotations by type. * * @param sortOrder @@ -2595,10 +2500,6 @@ public class GAlignFrame extends JInternalFrame { } - protected void showProducts_actionPerformed(ActionEvent e) - { - } - protected void buildSortByAnnotationScoresMenu() { } @@ -2902,7 +2803,7 @@ public class GAlignFrame extends JInternalFrame { } - protected void LoadtreeMenuItem_actionPerformed(ActionEvent e) + protected void loadTreeMenuItem_actionPerformed(ActionEvent e) { } @@ -3160,4 +3061,50 @@ public class GAlignFrame extends JInternalFrame { this.annotationSortOrder = annotationSortOrder; } + + public Map getAccelerators() + { + return this.accelerators; + } + + /** + * Returns the selected index of the tabbed pane, or -1 if none selected + * (including the case where the tabbed pane has not been made visible). + * + * @return + */ + public int getTabIndex() + { + return tabbedPane.getSelectedIndex(); + } + + public JPanel getStatusPanel() + { + return statusPanel; + } + + /** + * Sets a reference to the containing split frame. Also makes the 'toggle + * split view' menu item visible and checked. + * + * @param sf + */ + public void setSplitFrame(SplitContainerI sf) + { + this.splitFrame = sf; + if (sf != null) + { + this.showComplementMenuItem.setVisible(true); + this.showComplementMenuItem.setState(true); + } + } + + public SplitContainerI getSplitViewContainer() + { + return this.splitFrame; + } + + protected void showComplement_actionPerformed(boolean state) + { + } } diff --git a/src/jalview/jbgui/GPDBSearchPanel.java b/src/jalview/jbgui/GPDBSearchPanel.java new file mode 100644 index 0000000..29a0014 --- /dev/null +++ b/src/jalview/jbgui/GPDBSearchPanel.java @@ -0,0 +1,242 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2) + * Copyright (C) 2014 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 . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ + +package jalview.jbgui; + +import jalview.gui.Desktop; +import jalview.jbgui.PDBDocFieldPreferences.PreferenceSource; +import jalview.util.MessageManager; +import jalview.ws.dbsources.PDBRestClient.PDBDocField; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTabbedPane; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +/** + * GUI layout for PDB Fetch Panel + * + * @author tcnofoegbu + * + */ +@SuppressWarnings("serial") +public abstract class GPDBSearchPanel extends JPanel +{ + protected String frameTitle = MessageManager + .getString("label.pdb_sequence_getcher"); + + protected JInternalFrame mainFrame = new JInternalFrame(frameTitle); + + protected JComboBox cmb_searchTarget = new JComboBox(); + + protected JButton btn_ok = new JButton(); + + protected JButton btn_back = new JButton(); + + protected JButton btn_cancel = new JButton(); + + protected JTextField txt_search = new JTextField(20); + + protected JTable tbl_summary = new JTable(); + + protected JScrollPane scrl_searchResult = new JScrollPane( +tbl_summary); + + private JTabbedPane tabbedPane = new JTabbedPane(); + + private PDBDocFieldPreferences pdbDocFieldPrefs = new PDBDocFieldPreferences( + PreferenceSource.SEARCH_SUMMARY); + + private JPanel pnl_actions = new JPanel(); + + private JPanel pnl_results = new JPanel(); + + private JPanel pnl_inputs = new JPanel(); + + private BorderLayout mainLayout = new BorderLayout(); + + public GPDBSearchPanel() + { + try + { + jbInit(); + mainFrame.invalidate(); + mainFrame.pack(); + } catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * Initializes the GUI default properties + * + * @throws Exception + */ + private void jbInit() throws Exception + { + tbl_summary.setAutoCreateRowSorter(true); + btn_back.setFont(new java.awt.Font("Verdana", 0, 12)); + btn_back.setText(MessageManager.getString("action.back")); + btn_back.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(ActionEvent e) + { + btn_back_ActionPerformed(); + } + }); + btn_ok.setFont(new java.awt.Font("Verdana", 0, 12)); + btn_ok.setText(MessageManager.getString("action.ok")); + btn_ok.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(ActionEvent e) + { + btn_ok_ActionPerformed(); + } + }); + btn_cancel.setFont(new java.awt.Font("Verdana", 0, 12)); + btn_cancel.setText(MessageManager.getString("action.cancel")); + btn_cancel.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(ActionEvent e) + { + btn_cancel_ActionPerformed(); + } + }); + + scrl_searchResult.setPreferredSize(new Dimension(500, 300)); + scrl_searchResult + .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + + cmb_searchTarget.setFont(new java.awt.Font("Verdana", 0, 12)); + cmb_searchTarget.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + txt_search_ActionPerformed(); + } + }); + + populateCmbSearchTargetOptions(); + + txt_search.setFont(new java.awt.Font("Verdana", 0, 12)); + txt_search.getDocument().addDocumentListener(new DocumentListener() + { + @Override + public void insertUpdate(DocumentEvent e) + { + txt_search_ActionPerformed(); + } + + @Override + public void removeUpdate(DocumentEvent e) + { + txt_search_ActionPerformed(); + } + + @Override + public void changedUpdate(DocumentEvent e) + { + txt_search_ActionPerformed(); + } + }); + + final String searchTabTitle = MessageManager + .getString("label.search_result"); + ChangeListener changeListener = new ChangeListener() + { + public void stateChanged(ChangeEvent changeEvent) + { + JTabbedPane sourceTabbedPane = (JTabbedPane) changeEvent + .getSource(); + int index = sourceTabbedPane.getSelectedIndex(); + if (sourceTabbedPane.getTitleAt(index).equals(searchTabTitle)) + { + txt_search_ActionPerformed(); + } + } + }; + tabbedPane.addChangeListener(changeListener); + tabbedPane.setPreferredSize(new Dimension(500, 300)); + tabbedPane.add(searchTabTitle, scrl_searchResult); + tabbedPane.add( + MessageManager.getString("label.configure_displayed_columns"), + pdbDocFieldPrefs); + + pnl_actions.add(btn_back); + pnl_actions.add(btn_ok); + pnl_actions.add(btn_cancel); + + pnl_results.add(tabbedPane); + pnl_inputs.add(cmb_searchTarget); + pnl_inputs.add(txt_search); + + this.setLayout(mainLayout); + this.add(pnl_inputs, java.awt.BorderLayout.NORTH); + this.add(pnl_results, java.awt.BorderLayout.CENTER); + this.add(pnl_actions, java.awt.BorderLayout.SOUTH); + mainFrame.setVisible(true); + mainFrame.setContentPane(this); + mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + Desktop.addInternalFrame(mainFrame, frameTitle, 800, 400); + } + + public JComboBox getCmbSearchTarget() + { + return cmb_searchTarget; + } + + public JTextField getTxtSearch() + { + return txt_search; + } + + public JInternalFrame getMainFrame() + { + return mainFrame; + } + + public abstract void txt_search_ActionPerformed(); + + public abstract void btn_ok_ActionPerformed(); + + public abstract void btn_back_ActionPerformed(); + + public abstract void btn_cancel_ActionPerformed(); + + public abstract void populateCmbSearchTargetOptions(); + +} diff --git a/src/jalview/jbgui/GPreferences.java b/src/jalview/jbgui/GPreferences.java index 8f226ef..1d35477 100755 --- a/src/jalview/jbgui/GPreferences.java +++ b/src/jalview/jbgui/GPreferences.java @@ -22,6 +22,7 @@ package jalview.jbgui; import jalview.gui.JvSwingUtils; import jalview.gui.StructureViewer.ViewerType; +import jalview.jbgui.PDBDocFieldPreferences.PreferenceSource; import jalview.util.MessageManager; import java.awt.BorderLayout; @@ -149,6 +150,7 @@ public class GPreferences extends JPanel protected JTextField chimeraPath = new JTextField(); + /* * Colours tab components */ @@ -156,7 +158,9 @@ public class GPreferences extends JPanel protected JPanel maxColour = new JPanel(); - protected JComboBox colour = new JComboBox(); + protected JComboBox protColour = new JComboBox(); + + protected JComboBox nucColour = new JComboBox(); /* * Connections tab components @@ -692,16 +696,30 @@ public class GPreferences extends JPanel maxColour_actionPerformed(maxColour); } }); - colour.setFont(verdana11); - colour.setBounds(new Rectangle(172, 225, 155, 21)); - JLabel colourLabel = new JLabel(); - colourLabel.setFont(verdana11); - colourLabel.setHorizontalAlignment(SwingConstants.RIGHT); - colourLabel.setText(MessageManager.getString("label.alignment_colour") + + protColour.setFont(verdana11); + protColour.setBounds(new Rectangle(172, 225, 155, 21)); + JLabel protColourLabel = new JLabel(); + protColourLabel.setFont(verdana11); + protColourLabel.setHorizontalAlignment(SwingConstants.LEFT); + protColourLabel.setText(MessageManager + .getString("label.prot_alignment_colour") + " "); + JvSwingUtils.addtoLayout(coloursTab, MessageManager + .getString("label.default_colour_scheme_for_alignment"), + protColourLabel, protColour); + + nucColour.setFont(verdana11); + nucColour.setBounds(new Rectangle(172, 240, 155, 21)); + JLabel nucColourLabel = new JLabel(); + nucColourLabel.setFont(verdana11); + nucColourLabel.setHorizontalAlignment(SwingConstants.LEFT); + nucColourLabel.setText(MessageManager + .getString("label.nuc_alignment_colour") + " "); JvSwingUtils.addtoLayout(coloursTab, MessageManager .getString("label.default_colour_scheme_for_alignment"), - colourLabel, colour); + nucColourLabel, nucColour); + JPanel annotationShding = new JPanel(); annotationShding.setBorder(new TitledBorder(MessageManager .getString("label.annotation_shading_default"))); @@ -729,8 +747,8 @@ public class GPreferences extends JPanel .getString("label.structure_options"))); structureTab.setLayout(null); final int width = 400; - final int height = 23; - final int lineSpacing = 30; + final int height = 22; + final int lineSpacing = 25; int ypos = 30; structFromPdb.setFont(verdana11); @@ -824,9 +842,23 @@ public class GPreferences extends JPanel }); structureTab.add(chimeraPath); + ypos += lineSpacing; + // scrl_pdbDocFieldConfig.setPreferredSize(new Dimension(450, 100)); + // scrl_pdbDocFieldConfig + // .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + // scrl_pdbDocFieldConfig.setBounds(); + PDBDocFieldPreferences docFieldPref = new PDBDocFieldPreferences( + PreferenceSource.PREFERENCES); + docFieldPref.setBounds(new Rectangle(10, ypos + 5, 450, 120)); + structureTab.add(docFieldPref); + + + + return structureTab; } + /** * Action on choosing a structure viewer from combobox options. * diff --git a/src/jalview/jbgui/GSplitFrame.java b/src/jalview/jbgui/GSplitFrame.java new file mode 100644 index 0000000..a377571 --- /dev/null +++ b/src/jalview/jbgui/GSplitFrame.java @@ -0,0 +1,142 @@ +package jalview.jbgui; + +import java.awt.Component; +import java.awt.MouseInfo; +import java.awt.Point; +import java.awt.Rectangle; + +import javax.swing.JInternalFrame; +import javax.swing.JSplitPane; +import javax.swing.plaf.basic.BasicInternalFrameUI; + +import jalview.util.Platform; + +public class GSplitFrame extends JInternalFrame +{ + private static final long serialVersionUID = 1L; + + private GAlignFrame topFrame; + + private GAlignFrame bottomFrame; + + private JSplitPane splitPane; + + /** + * Constructor + * + * @param top + * @param bottom + */ + public GSplitFrame(GAlignFrame top, GAlignFrame bottom) + { + this.topFrame = top; + this.bottomFrame = bottom; + + hideTitleBars(); + + addSplitPane(); + } + + /** + * Create and add the split pane containing the top and bottom components. + */ + protected void addSplitPane() + { + splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topFrame, + bottomFrame); + splitPane.setVisible(true); + final double ratio = topFrame.getHeight() + / (double) (topFrame.getHeight() + bottomFrame.getHeight()); + splitPane.setDividerLocation(ratio); + splitPane.setResizeWeight(ratio); + splitPane.setDividerSize(5); + add(splitPane); + } + + /** + * Try to hide the title bars as a waste of precious space. + * + * @see http + * ://stackoverflow.com/questions/7218971/java-method-works-on-windows + * -but-not-macintosh -java + */ + protected void hideTitleBars() + { + if (new Platform().isAMac()) + { + // this saves some space - but doesn't hide the title bar + topFrame.putClientProperty("JInternalFrame.isPalette", true); + // topFrame.getRootPane().putClientProperty("Window.style", "small"); + bottomFrame.putClientProperty("JInternalFrame.isPalette", true); + } + else + { + ((BasicInternalFrameUI) topFrame.getUI()).setNorthPane(null); + ((BasicInternalFrameUI) bottomFrame.getUI()).setNorthPane(null); + } + } + + public GAlignFrame getTopFrame() + { + return topFrame; + } + + public GAlignFrame getBottomFrame() + { + return bottomFrame; + } + + /** + * Returns the split pane component the mouse is in, or null if neither. + * + * @return + */ + protected GAlignFrame getFrameAtMouse() + { + Point loc = MouseInfo.getPointerInfo().getLocation(); + + if (isIn(loc, splitPane.getTopComponent())) + { + return getTopFrame(); + } + else if (isIn(loc, splitPane.getBottomComponent())) + { + return getBottomFrame(); + } + return null; + } + + private boolean isIn(Point loc, Component comp) + { + if (!comp.isVisible()) + { + return false; + } + Point p = comp.getLocationOnScreen(); + Rectangle r = new Rectangle(p.x, p.y, comp.getWidth(), comp.getHeight()); + return r.contains(loc); + } + + /** + * Make the complement of the specified split component visible or hidden, + * adjusting the position of the split divide. + */ + public void setComplementVisible(Object alignFrame, boolean show) + { + if (alignFrame == this.topFrame) + { + this.bottomFrame.setVisible(show); + } + else if (alignFrame == this.bottomFrame) + { + this.topFrame.setVisible(show); + } + if (show) + { + // SplitPane needs nudging to restore 50-50 split + // TODO save/restore other ratios + splitPane.setDividerLocation(0.5d); + } + validate(); + } +} diff --git a/src/jalview/jbgui/GStructureChooser.java b/src/jalview/jbgui/GStructureChooser.java new file mode 100644 index 0000000..b79a7f7 --- /dev/null +++ b/src/jalview/jbgui/GStructureChooser.java @@ -0,0 +1,487 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2) + * Copyright (C) 2014 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 . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ + +package jalview.jbgui; + +import jalview.datamodel.SequenceI; +import jalview.gui.AlignmentPanel; +import jalview.gui.Desktop; +import jalview.jbgui.PDBDocFieldPreferences.PreferenceSource; +import jalview.util.MessageManager; + +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTabbedPane; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +@SuppressWarnings("serial") +/** + * GUI layout for structure chooser + * @author tcnofoegbu + * + */ +public abstract class GStructureChooser extends JPanel implements + ItemListener +{ + protected String frameTitle = MessageManager + .getString("label.structure_chooser"); + + protected JInternalFrame mainFrame = new JInternalFrame(frameTitle); + + protected JComboBox cmb_filterOption = new JComboBox(); + + protected AlignmentPanel ap; + + protected JLabel lbl_result = new JLabel( + MessageManager.getString("label.select")); + + protected JButton btn_view = new JButton(); + + protected JButton btn_cancel = new JButton(); + + protected JButton btn_pdbFromFile = new JButton(); + + protected JTextField txt_search = new JTextField(14); + + private JPanel pnl_actions = new JPanel(); + + private JPanel pnl_filter = new JPanel(); + + private JPanel pnl_idInput = new JPanel(new FlowLayout()); + + private JPanel pnl_fileChooser = new JPanel(new FlowLayout()); + + private JPanel pnl_idInputBL = new JPanel(new BorderLayout()); + + private JPanel pnl_fileChooserBL = new JPanel(new BorderLayout()); + + protected JPanel pnl_switchableViews = new JPanel(new CardLayout()); + + protected CardLayout layout_switchableViews = (CardLayout) (pnl_switchableViews + .getLayout()); + + private BorderLayout mainLayout = new BorderLayout(); + + protected JCheckBox chk_rememberSettings = new JCheckBox( + MessageManager.getString("label.dont_ask_me_again")); + + protected JCheckBox chk_invertFilter = new JCheckBox( + MessageManager.getString("label.invert")); + + protected ImageIcon loadingImage = new ImageIcon(getClass().getResource( + "/images/loading.gif")); + + protected ImageIcon goodImage = new ImageIcon(getClass().getResource( + "/images/good.png")); + + protected ImageIcon errorImage = new ImageIcon(getClass().getResource( + "/images/error.png")); + + protected JLabel lbl_loading = new JLabel(loadingImage); + + protected JLabel lbl_pdbManualFetchStatus = new JLabel(errorImage); + + protected JLabel lbl_fromFileStatus = new JLabel(errorImage); + + + protected AssciateSeqPanel idInputAssSeqPanel = new AssciateSeqPanel(); + + protected AssciateSeqPanel fileChooserAssSeqPanel = new AssciateSeqPanel(); + + protected static final String VIEWS_FILTER = "VIEWS_FILTER"; + + protected static final String VIEWS_FROM_FILE = "VIEWS_FROM_FILE"; + + protected static final String VIEWS_ENTER_ID = "VIEWS_ENTER_ID"; + + protected JTable tbl_summary = new JTable(); + + protected JScrollPane scrl_foundStructures = new JScrollPane( + tbl_summary); + + private JTabbedPane tabbedPane = new JTabbedPane(); + + private PDBDocFieldPreferences pdbDocFieldPrefs = new PDBDocFieldPreferences( + PreferenceSource.STRUCTURE_CHOOSER); + + public GStructureChooser() + { + try + { + jbInit(); + mainFrame.setVisible(false); + mainFrame.invalidate(); + mainFrame.pack(); + } catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * Initializes the GUI default properties + * + * @throws Exception + */ + private void jbInit() throws Exception + { + tbl_summary.setAutoCreateRowSorter(true); + btn_view.setFont(new java.awt.Font("Verdana", 0, 12)); + btn_view.setText(MessageManager.getString("action.view")); + btn_view.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(ActionEvent e) + { + ok_ActionPerformed(); + } + }); + btn_cancel.setFont(new java.awt.Font("Verdana", 0, 12)); + btn_cancel.setText(MessageManager.getString("action.cancel")); + btn_cancel.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(ActionEvent e) + { + mainFrame.dispose(); + } + }); + + btn_pdbFromFile.setFont(new java.awt.Font("Verdana", 0, 12)); + String btn_title = MessageManager.getString("label.select_pdb_file"); + btn_pdbFromFile.setText(btn_title + " "); + btn_pdbFromFile.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(ActionEvent e) + { + pdbFromFile_actionPerformed(); + } + }); + + scrl_foundStructures.setPreferredSize(new Dimension(500, 300)); + scrl_foundStructures + .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + + cmb_filterOption.setFont(new java.awt.Font("Verdana", 0, 12)); + chk_invertFilter.setFont(new java.awt.Font("Verdana", 0, 12)); + chk_rememberSettings.setFont(new java.awt.Font("Verdana", 0, 12)); + + + txt_search.setToolTipText(MessageManager + .getString("label.enter_pdb_id")); + cmb_filterOption.setToolTipText(MessageManager + .getString("info.select_filter_option")); + txt_search.getDocument().addDocumentListener(new DocumentListener() + { + @Override + public void insertUpdate(DocumentEvent e) + { + txt_search_ActionPerformed(); + } + + @Override + public void removeUpdate(DocumentEvent e) + { + txt_search_ActionPerformed(); + } + + @Override + public void changedUpdate(DocumentEvent e) + { + txt_search_ActionPerformed(); + } + }); + + cmb_filterOption.addItemListener(this); + chk_invertFilter.addItemListener(this); + + pnl_actions.add(chk_rememberSettings); + pnl_actions.add(btn_view); + pnl_actions.add(btn_cancel); + + // pnl_filter.add(lbl_result); + pnl_filter.add(cmb_filterOption); + pnl_filter.add(lbl_loading); + pnl_filter.add(chk_invertFilter); + lbl_loading.setVisible(false); + + pnl_idInput.add(txt_search); + pnl_idInput.add(lbl_pdbManualFetchStatus); + + pnl_fileChooser.add(btn_pdbFromFile); + pnl_fileChooser.add(lbl_fromFileStatus); + + pnl_fileChooserBL.add(fileChooserAssSeqPanel, BorderLayout.NORTH); + pnl_fileChooserBL.add(pnl_fileChooser, BorderLayout.CENTER); + + pnl_idInputBL.add(idInputAssSeqPanel, BorderLayout.NORTH); + pnl_idInputBL.add(pnl_idInput, BorderLayout.CENTER); + + final String foundStructureSummary = MessageManager + .getString("label.found_structures_summary"); + + ChangeListener changeListener = new ChangeListener() + { + public void stateChanged(ChangeEvent changeEvent) + { + JTabbedPane sourceTabbedPane = (JTabbedPane) changeEvent + .getSource(); + int index = sourceTabbedPane.getSelectedIndex(); + if (sourceTabbedPane.getTitleAt(index) + .equals(foundStructureSummary)) + { + tabRefresh(); + } + } + }; + tabbedPane.addChangeListener(changeListener); + tabbedPane.setPreferredSize(new Dimension(500, 300)); + tabbedPane.add(foundStructureSummary, scrl_foundStructures); + tabbedPane.add( + MessageManager.getString("label.configure_displayed_columns"), + pdbDocFieldPrefs); + + + pnl_switchableViews.add(pnl_fileChooserBL, VIEWS_FROM_FILE); + pnl_switchableViews.add(pnl_idInputBL, VIEWS_ENTER_ID); + pnl_switchableViews.add(tabbedPane, VIEWS_FILTER); + + this.setLayout(mainLayout); + this.add(pnl_filter, java.awt.BorderLayout.NORTH); + this.add(pnl_switchableViews, java.awt.BorderLayout.CENTER); + this.add(pnl_actions, java.awt.BorderLayout.SOUTH); + + mainFrame.setVisible(true); + mainFrame.setContentPane(this); + mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + Desktop.addInternalFrame(mainFrame, frameTitle, 800, 400); + } + + + @Override + /** + * Event listener for the 'filter' combo-box and 'invert' check-box + */ + public void itemStateChanged(ItemEvent e) + { + stateChanged(e); + } + + /** + * This inner class provides the data model for the structure filter combo-box + * + * @author tcnofoegbu + * + */ + public class FilterOption + { + private String name; + + private String value; + + private String view; + + public FilterOption(String name, String value, String view) + { + this.name = name; + this.value = value; + this.view = view; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getValue() + { + return value; + } + + public void setValue(String value) + { + this.value = value; + } + + public String getView() + { + return view; + } + + public void setView(String view) + { + this.view = view; + } + + public String toString() + { + return this.name; + } + } + + /** + * This inner class provides the provides the data model for associate + * sequence combo-box - cmb_assSeq + * + * @author tcnofoegbu + * + */ + public class AssociateSeqOptions + { + private SequenceI sequence; + private String name; + + public AssociateSeqOptions(SequenceI seq) + { + this.sequence = seq; + this.name = (seq.getName().length() >= 23) ? seq.getName().substring( + 0, 23) : seq.getName(); + } + + public AssociateSeqOptions(String name, SequenceI seq) + { + this.name = name; + this.sequence = seq; + } + + public String toString() + { + return name; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public SequenceI getSequence() + { + return sequence; + } + + public void setSequence(SequenceI sequence) + { + this.sequence = sequence; + } + + } + + /** + * This inner class holds the Layout and configuration of the panel which + * handles association of manually fetched structures to a unique sequence + * when more than one sequence selection is made + * + * @author tcnofoegbu + * + */ + public class AssciateSeqPanel extends JPanel implements ItemListener + { + private JComboBox cmb_assSeq = new JComboBox(); + + private JLabel lbl_associateSeq = new JLabel(); + + public AssciateSeqPanel() + { + this.setLayout(new FlowLayout()); + this.add(cmb_assSeq); + this.add(lbl_associateSeq); + cmb_assSeq.setToolTipText(MessageManager + .getString("info.associate_wit_sequence")); + cmb_assSeq.addItemListener(this); + } + + public void loadCmbAssSeq() + { + populateCmbAssociateSeqOptions(cmb_assSeq, lbl_associateSeq); + } + + public JComboBox getCmb_assSeq() + { + return cmb_assSeq; + } + + public void setCmb_assSeq(JComboBox cmb_assSeq) + { + this.cmb_assSeq = cmb_assSeq; + } + + @Override + public void itemStateChanged(ItemEvent e) + { + if (e.getStateChange() == ItemEvent.SELECTED) + { + cmbAssSeqStateChanged(); + } + } + } + + public JComboBox getCmbFilterOption() + { + return cmb_filterOption; + } + + protected abstract void stateChanged(ItemEvent e); + + protected abstract void updateCurrentView(); + + protected abstract void populateFilterComboBox(); + + protected abstract void ok_ActionPerformed(); + + protected abstract void pdbFromFile_actionPerformed(); + + protected abstract void txt_search_ActionPerformed(); + + public abstract void populateCmbAssociateSeqOptions( + JComboBox cmb_assSeq, JLabel lbl_associateSeq); + + public abstract void cmbAssSeqStateChanged(); + + public abstract void tabRefresh(); +} diff --git a/src/jalview/jbgui/GTreePanel.java b/src/jalview/jbgui/GTreePanel.java index 3417734..d067753 100755 --- a/src/jalview/jbgui/GTreePanel.java +++ b/src/jalview/jbgui/GTreePanel.java @@ -22,10 +22,19 @@ package jalview.jbgui; import jalview.util.MessageManager; -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.event.*; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JInternalFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JScrollPane; +import javax.swing.event.MenuEvent; +import javax.swing.event.MenuListener; public class GTreePanel extends JInternalFrame { @@ -124,7 +133,7 @@ public class GTreePanel extends JInternalFrame { public void actionPerformed(ActionEvent e) { - sortByTree_actionPerformed(e); + sortByTree_actionPerformed(); } }); font.setText(MessageManager.getString("action.font")); @@ -282,7 +291,7 @@ public class GTreePanel extends JInternalFrame { } - public void sortByTree_actionPerformed(ActionEvent e) + public void sortByTree_actionPerformed() { } diff --git a/src/jalview/jbgui/PDBDocFieldPreferences.java b/src/jalview/jbgui/PDBDocFieldPreferences.java new file mode 100644 index 0000000..2021d0b --- /dev/null +++ b/src/jalview/jbgui/PDBDocFieldPreferences.java @@ -0,0 +1,228 @@ +package jalview.jbgui; + +import jalview.ws.dbsources.PDBRestClient.PDBDocField; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; + +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.table.AbstractTableModel; + +@SuppressWarnings("serial") +public class PDBDocFieldPreferences extends JScrollPane +{ + protected JTable tbl_pdbDocFieldConfig = new JTable(); + + protected JScrollPane scrl_pdbDocFieldConfig = new JScrollPane( + tbl_pdbDocFieldConfig); + + private HashMap map = new HashMap(); + + private static Collection searchSummaryFields = new HashSet(); + + private static Collection structureSummaryFields = new HashSet(); + + public enum PreferenceSource + { + SEARCH_SUMMARY, STRUCTURE_CHOOSER, PREFERENCES; + } + + private PreferenceSource currentSource; + + static + { + searchSummaryFields.add(PDBDocField.PDB_ID); + searchSummaryFields.add(PDBDocField.TITLE); + + structureSummaryFields.add(PDBDocField.PDB_ID); + structureSummaryFields.add(PDBDocField.TITLE); + } + + public PDBDocFieldPreferences(PreferenceSource source) + { + tbl_pdbDocFieldConfig.setAutoCreateRowSorter(true); + this.getViewport().add(tbl_pdbDocFieldConfig); + this.currentSource = source; + + String[] columnNames = null; + switch (source) + { + case SEARCH_SUMMARY: + columnNames = new String[] + { "PDB Feild", "Show in search summary" }; + break; + case STRUCTURE_CHOOSER: + columnNames = new String[] + { "PDB Feild", "Show in structure summary" }; + break; + case PREFERENCES: + columnNames = new String[] + { "PDB Feild", "Show in search summary", "Show in structure summary" }; + break; + default: + break; + } + + Object[][] data = new Object[PDBDocField.values().length - 1][3]; + int x = 0; + for (PDBDocField field : PDBDocField.values()) + { + if (field.getName().equalsIgnoreCase("all")) + { + continue; + } + + switch (source) + { + case SEARCH_SUMMARY: + data[x++] = new Object[] + { field.getName(), searchSummaryFields.contains(field) }; + break; + case STRUCTURE_CHOOSER: + data[x++] = new Object[] + { field.getName(), structureSummaryFields.contains(field) }; + break; + case PREFERENCES: + data[x++] = new Object[] + { field.getName(), searchSummaryFields.contains(field), + structureSummaryFields.contains(field) }; + break; + default: + break; + } + map.put(field.getName(), field); + } + + PDBFieldTableModel model = new PDBFieldTableModel(columnNames, data); + tbl_pdbDocFieldConfig.setModel(model); + } + + public static Collection getSearchSummaryFields() + { + return searchSummaryFields; + } + + public static void setSearchSummaryFields( + Collection searchSummaryFields) + { + PDBDocFieldPreferences.searchSummaryFields = searchSummaryFields; + } + + public static Collection getStructureSummaryFields() + { + return structureSummaryFields; + } + + public static void setStructureSummaryFields( + Collection structureSummaryFields) + { + PDBDocFieldPreferences.structureSummaryFields = structureSummaryFields; + } + + class PDBFieldTableModel extends AbstractTableModel + { + + public PDBFieldTableModel(String[] columnNames, Object[][] data) + { + this.data = data; + this.columnNames = columnNames; + } + + private Object[][] data; + + private String[] columnNames; + + public int getColumnCount() + { + return columnNames.length; + } + + public int getRowCount() + { + return data.length; + } + + public String getColumnName(int col) + { + return columnNames[col]; + } + + public Object getValueAt(int row, int col) + { + return data[row][col]; + } + + /* + * JTable uses this method to determine the default renderer/ editor for + * each cell. If we didn't implement this method, then the last column would + * contain text ("true"/"false"), rather than a check box. + */ + public Class getColumnClass(int c) + { + return getValueAt(0, c).getClass(); + } + + /* + * Don't need to implement this method unless your table's editable. + */ + public boolean isCellEditable(int row, int col) + { + // Note that the data/cell address is constant, + // no matter where the cell appears onscreen. + return col == 1 || col == 2; + + } + + /* + * Don't need to implement this method unless your table's data can change. + */ + public void setValueAt(Object value, int row, int col) + { + data[row][col] = value; + fireTableCellUpdated(row, col); + + String name = getValueAt(row, 0).toString(); + boolean selected = ((Boolean) value).booleanValue(); + + PDBDocField pdbField = map.get(name); + + if (currentSource == PreferenceSource.SEARCH_SUMMARY) + { + updatePrefs(searchSummaryFields, pdbField, selected); + } + else if (currentSource == PreferenceSource.STRUCTURE_CHOOSER) + { + updatePrefs(structureSummaryFields, pdbField, selected); + } + else if (currentSource == PreferenceSource.PREFERENCES) + { + if (col == 1) + { + updatePrefs(searchSummaryFields, pdbField, selected); + } + else if (col == 2) + { + updatePrefs(structureSummaryFields, pdbField, selected); + } + } + } + + private void updatePrefs(Collection prefConfig, + PDBDocField pdbField, + boolean selected) + { + if (prefConfig.contains(pdbField) && !selected) + { + prefConfig.remove(pdbField); + } + + if (!prefConfig.contains(pdbField) && selected) + { + prefConfig.add(pdbField); + } + } + + } +} diff --git a/src/jalview/renderer/AnnotationRenderer.java b/src/jalview/renderer/AnnotationRenderer.java index d4fda25..2ba7aff 100644 --- a/src/jalview/renderer/AnnotationRenderer.java +++ b/src/jalview/renderer/AnnotationRenderer.java @@ -21,6 +21,7 @@ package jalview.renderer; import jalview.analysis.AAFrequency; +import jalview.analysis.CodingUtils; import jalview.analysis.StructureFrequency; import jalview.api.AlignViewportI; import jalview.datamodel.AlignmentAnnotation; @@ -142,6 +143,8 @@ public class AnnotationRenderer private Hashtable[] hconsensus; + private Hashtable[] complementConsensus; + private Hashtable[] hStrucConsensus; private boolean av_ignoreGapsConsensus; @@ -298,24 +301,37 @@ public class AnnotationRenderer profcolour = av.getAlignment().isNucleotide() ? new jalview.schemes.NucleotideColourScheme() : new jalview.schemes.ZappoColourScheme(); } - boolean rna = av.getAlignment().isNucleotide(); columnSelection = av.getColumnSelection(); - hconsensus = av.getSequenceConsensusHash();// hconsensus; - hStrucConsensus = av.getRnaStructureConsensusHash(); // hStrucConsensus; - av_ignoreGapsConsensus = av.getIgnoreGapsConsensus(); + hconsensus = av.getSequenceConsensusHash(); + complementConsensus = av.getComplementConsensusHash(); + hStrucConsensus = av.getRnaStructureConsensusHash(); + av_ignoreGapsConsensus = av.isIgnoreGapsConsensus(); } + /** + * Returns profile data; the first element is the profile type, the second is + * the number of distinct values, the third the total count, and the remainder + * depend on the profile type. + * + * @param aa + * @param column + * @return + */ public int[] getProfileFor(AlignmentAnnotation aa, int column) { // TODO : consider refactoring the global alignment calculation // properties/rendering attributes as a global 'alignment group' which holds // all vis settings for the alignment as a whole rather than a subset // - if (aa.autoCalculated && aa.label.startsWith("Consensus")) + if (aa.autoCalculated + && (aa.label.startsWith("Consensus") || aa.label + .startsWith("cDNA Consensus"))) { + boolean forComplement = aa.label.startsWith("cDNA Consensus"); if (aa.groupRef != null && aa.groupRef.consensusData != null && aa.groupRef.isShowSequenceLogo()) { + // TODO? group consensus for cDNA complement return AAFrequency.extractProfile( aa.groupRef.consensusData[column], aa.groupRef.getIgnoreGapsConsensus()); @@ -324,8 +340,16 @@ public class AnnotationRenderer // be stored if (aa.groupRef == null && aa.sequenceRef == null) { - return AAFrequency.extractProfile(hconsensus[column], - av_ignoreGapsConsensus); + if (forComplement) + { + return AAFrequency.extractCdnaProfile( + complementConsensus[column], av_ignoreGapsConsensus); + } + else + { + return AAFrequency.extractProfile(hconsensus[column], + av_ignoreGapsConsensus); + } } } else @@ -400,12 +424,15 @@ public class AnnotationRenderer boolean validRes = false; boolean validEnd = false; boolean labelAllCols = false; - boolean centreColLabels, centreColLabelsDef = av - .getCentreColumnLabels(); + boolean centreColLabels; + boolean centreColLabelsDef = av.isCentreColumnLabels(); boolean scaleColLabel = false; - AlignmentAnnotation consensusAnnot = av - .getAlignmentConsensusAnnotation(), structConsensusAnnot = av + final AlignmentAnnotation consensusAnnot = av + .getAlignmentConsensusAnnotation(); + final AlignmentAnnotation structConsensusAnnot = av .getAlignmentStrucConsensusAnnotation(); + final AlignmentAnnotation complementConsensusAnnot = av + .getComplementConsensusAnnotation(); boolean renderHistogram = true, renderProfile = true, normaliseProfile = false, isRNA = rna; BitSet graphGroupDrawn = new BitSet(); @@ -432,7 +459,8 @@ public class AnnotationRenderer renderProfile = row.groupRef.isShowSequenceLogo(); normaliseProfile = row.groupRef.isNormaliseSequenceLogo(); } - else if (row == consensusAnnot || row == structConsensusAnnot) + else if (row == consensusAnnot || row == structConsensusAnnot + || row == complementConsensusAnnot) { renderHistogram = av_renderHistogram; renderProfile = av_renderProfile; @@ -556,6 +584,8 @@ public class AnnotationRenderer { validRes = true; } + final String displayChar = validRes ? row_annotations[column].displayCharacter + : null; if (x > -1) { if (activeRow == i) @@ -585,21 +615,19 @@ public class AnnotationRenderer g.setColor(Color.orange.darker()); g.fillRect(x * charWidth, y, charWidth, charHeight); } - if (validCharWidth - && validRes - && row_annotations[column].displayCharacter != null - && (row_annotations[column].displayCharacter.length() > 0)) + if (validCharWidth && validRes && displayChar != null + && (displayChar.length() > 0)) { - if (centreColLabels || scaleColLabel) + fmWidth = fm.charsWidth(displayChar.toCharArray(), 0, + displayChar.length()); + if (/* centreColLabels || */scaleColLabel) { - fmWidth = fm.charsWidth( - row_annotations[column].displayCharacter - .toCharArray(), 0, - row_annotations[column].displayCharacter.length()); - - if (scaleColLabel) - { + // fmWidth = fm.charsWidth(displayChar.toCharArray(), 0, + // displayChar.length()); + // + // if (scaleColLabel) + // { // justify the label and scale to fit in column if (fmWidth > charWidth) { @@ -611,14 +639,13 @@ public class AnnotationRenderer // and update the label's width to reflect the scaling. fmWidth = charWidth; } - } - } - else - { - fmWidth = fm - .charWidth(row_annotations[column].displayCharacter - .charAt(0)); + // } } + // TODO is it ok to use width of / show all characters here? + // else + // { + // fmWidth = fm.charWidth(displayChar.charAt(0)); + // } charOffset = (int) ((charWidth - fmWidth) / 2f); if (row_annotations[column].colour == null) @@ -632,17 +659,17 @@ public class AnnotationRenderer if (column == 0 || row.graph > 0) { - g.drawString(row_annotations[column].displayCharacter, - (x * charWidth) + charOffset, y + iconOffset); + g.drawString(displayChar, (x * charWidth) + charOffset, y + + iconOffset); } else if (row_annotations[column - 1] == null || (labelAllCols - || !row_annotations[column].displayCharacter - .equals(row_annotations[column - 1].displayCharacter) || (row_annotations[column].displayCharacter + || !displayChar + .equals(row_annotations[column - 1].displayCharacter) || (displayChar .length() < 2 && row_annotations[column].secondaryStructure == ' '))) { - g.drawString(row_annotations[column].displayCharacter, x - * charWidth + charOffset, y + iconOffset); + g.drawString(displayChar, x * charWidth + charOffset, y + + iconOffset); } g.setFont(ofont); } @@ -655,7 +682,7 @@ public class AnnotationRenderer if (ss == '(') { // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf(')') > -1) + if (displayChar.indexOf(')') > -1) { ss = ')'; @@ -664,7 +691,7 @@ public class AnnotationRenderer } if (ss == '[') { - if ((row_annotations[column].displayCharacter.indexOf(']') > -1)) + if ((displayChar.indexOf(']') > -1)) { ss = ']'; @@ -673,7 +700,7 @@ public class AnnotationRenderer if (ss == '{') { // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('}') > -1) + if (displayChar.indexOf('}') > -1) { ss = '}'; @@ -682,7 +709,7 @@ public class AnnotationRenderer if (ss == '<') { // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('<') > -1) + if (displayChar.indexOf('<') > -1) { ss = '>'; @@ -691,7 +718,7 @@ public class AnnotationRenderer if (ss >= 65) { // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf(ss + 32) > -1) + if (displayChar.indexOf(ss + 32) > -1) { ss = (char) (ss + 32); @@ -1303,10 +1330,16 @@ public class AnnotationRenderer if (renderProfile) { + /* + * {profile type, #values, total count, char1, pct1, char2, pct2...} + */ int profl[] = getProfileFor(_aa, column); + // just try to draw the logo if profl is not null - if (profl != null && profl[1] != 0) + if (profl != null && profl[2] != 0) { + boolean isStructureProfile = profl[0] == AlignmentAnnotation.STRUCTURE_PROFILE; + boolean isCdnaProfile = profl[0] == AlignmentAnnotation.CDNA_PROFILE; float ht = normaliseProfile ? y - _aa.graphHeight : y1; double htn = normaliseProfile ? _aa.graphHeight : (y2 - y1);// aa.graphHeight; double hght; @@ -1315,55 +1348,80 @@ public class AnnotationRenderer char[] dc; /** - * profl.length == 74 indicates that the profile of a secondary - * structure conservation row was accesed. Therefore dc gets length 2, - * to have space for a basepair instead of just a single nucleotide + * Render a single base for a sequence profile, a base pair for + * structure profile, and a triplet for a cdna profile */ - if (profl.length == 74) - { - dc = new char[2]; - } - else - { - dc = new char[1]; - } + dc = new char[isStructureProfile ? 2 : (isCdnaProfile ? 3 : 1)]; + LineMetrics lm = g.getFontMetrics(ofont).getLineMetrics("Q", g); - double scale = 1f / (normaliseProfile ? profl[1] : 100f); + double scale = 1f / (normaliseProfile ? profl[2] : 100f); float ofontHeight = 1f / lm.getAscent();// magnify to fill box double scl = 0.0; - for (int c = 2; c < profl[0];) - { - dc[0] = (char) profl[c++]; - if (_aa.label.startsWith("StrucConsensus")) + /* + * Traverse the character(s)/percentage data in the array + */ + int c = 3; + int valuesProcessed = 0; + // profl[1] is the number of values in the profile + while (valuesProcessed < profl[1]) + { + if (isStructureProfile) { + // todo can we encode a structure pair as an int, like codons? + dc[0] = (char) profl[c++]; dc[1] = (char) profl[c++]; } + else if (isCdnaProfile) + { + dc = CodingUtils.decodeCodon(profl[c++]); + } + else + { + dc[0] = (char) profl[c++]; + } wdth = charWidth; wdth /= fm.charsWidth(dc, 0, dc.length); ht += scl; + // next profl[] position is profile % for the character(s) + scl = htn * scale * profl[c++]; + lm = ofont.getLineMetrics(dc, 0, 1, g.getFontMetrics() + .getFontRenderContext()); + g.setFont(ofont.deriveFont(AffineTransform.getScaleInstance( + wdth, scl / lm.getAscent()))); + lm = g.getFontMetrics().getLineMetrics(dc, 0, 1, g); + + // Debug - render boxes around characters + // g.setColor(Color.red); + // g.drawRect(x*av.charWidth, (int)ht, av.charWidth, + // (int)(scl)); + // g.setColor(profcolour.findColour(dc[0]).darker()); + + /* + * Set character colour as per alignment colour scheme; use the + * codon translation if a cDNA profile + */ + Color colour = null; + if (isCdnaProfile) { - scl = htn * scale * profl[c++]; - lm = ofont.getLineMetrics(dc, 0, 1, g.getFontMetrics() - .getFontRenderContext()); - g.setFont(ofont.deriveFont(AffineTransform.getScaleInstance( - wdth, scl / lm.getAscent()))); - lm = g.getFontMetrics().getLineMetrics(dc, 0, 1, g); - - // Debug - render boxes around characters - // g.setColor(Color.red); - // g.drawRect(x*av.charWidth, (int)ht, av.charWidth, - // (int)(scl)); - // g.setColor(profcolour.findColour(dc[0]).darker()); - g.setColor(profcolour.findColour(dc[0], column, null)); - - hght = (ht + (scl - lm.getDescent() - lm.getBaselineOffsets()[lm - .getBaselineIndex()])); - - g.drawChars(dc, 0, dc.length, x * charWidth, (int) hght); + final String codonTranslation = ResidueProperties + .codonTranslate(new String(dc)); + colour = profcolour.findColour(codonTranslation.charAt(0), + column, null); } + else + { + colour = profcolour.findColour(dc[0], column, null); + } + g.setColor(colour == Color.white ? Color.lightGray : colour); + + hght = (ht + (scl - lm.getDescent() - lm.getBaselineOffsets()[lm + .getBaselineIndex()])); + + g.drawChars(dc, 0, dc.length, x * charWidth, (int) hght); + valuesProcessed++; } g.setFont(ofont); } diff --git a/src/jalview/renderer/AwtRenderPanelI.java b/src/jalview/renderer/AwtRenderPanelI.java index af83df1..b86afbc 100644 --- a/src/jalview/renderer/AwtRenderPanelI.java +++ b/src/jalview/renderer/AwtRenderPanelI.java @@ -24,6 +24,14 @@ import java.awt.FontMetrics; import java.awt.Image; import java.awt.image.ImageObserver; +/** + * semi-insulated interface for rendering a faded image whilst a calculation is + * in progress on annotation panel. Will need to remove java.awt dependencies + * for Android/etc + * + * @author jprocter + * + */ public interface AwtRenderPanelI extends ImageObserver { /** diff --git a/src/jalview/renderer/seqfeatures/FeatureRenderer.java b/src/jalview/renderer/seqfeatures/FeatureRenderer.java index 5e6ac29..648f776 100644 --- a/src/jalview/renderer/seqfeatures/FeatureRenderer.java +++ b/src/jalview/renderer/seqfeatures/FeatureRenderer.java @@ -20,28 +20,6 @@ public class FeatureRenderer extends boolean offscreenRender = false; - /** - * DOCUMENT ME! - * - * @param g - * DOCUMENT ME! - * @param seq - * DOCUMENT ME! - * @param sg - * DOCUMENT ME! - * @param start - * DOCUMENT ME! - * @param end - * DOCUMENT ME! - * @param x1 - * DOCUMENT ME! - * @param y1 - * DOCUMENT ME! - * @param width - * DOCUMENT ME! - * @param height - * DOCUMENT ME! - */ protected SequenceI lastSeq; char s; @@ -99,7 +77,6 @@ public class FeatureRenderer extends charOffset = (av_charWidth - fm.charWidth(s)) / 2; g.drawString(String.valueOf(s), charOffset + (av_charWidth * (i - start)), pady); - } } } @@ -164,7 +141,6 @@ public class FeatureRenderer extends charOffset = (av_charWidth - fm.charWidth(s)) / 2; g.drawString(String.valueOf(s), charOffset + (av_charWidth * (i - start)), pady); - } } } @@ -188,30 +164,29 @@ public class FeatureRenderer extends return initialCol; } - final SequenceI aseq = (seq.getDatasetSequence() != null) ? seq - .getDatasetSequence() : seq; + SequenceFeature[] sequenceFeatures = seq.getSequenceFeatures(); if (seq != lastSeq) { lastSeq = seq; - sequenceFeatures = aseq.getSequenceFeatures(); - if (sequenceFeatures != null) + lastSequenceFeatures = sequenceFeatures; + if (lastSequenceFeatures != null) { - sfSize = sequenceFeatures.length; + sfSize = lastSequenceFeatures.length; } } else { - if (sequenceFeatures != aseq.getSequenceFeatures()) + if (lastSequenceFeatures != sequenceFeatures) { - sequenceFeatures = aseq.getSequenceFeatures(); - if (sequenceFeatures != null) + lastSequenceFeatures = sequenceFeatures; + if (lastSequenceFeatures != null) { - sfSize = sequenceFeatures.length; + sfSize = lastSequenceFeatures.length; } } } - if (sequenceFeatures == null || sfSize == 0) + if (lastSequenceFeatures == null || sfSize == 0) { return initialCol; } @@ -255,7 +230,7 @@ public class FeatureRenderer extends } - private volatile SequenceFeature[] sequenceFeatures; + private volatile SequenceFeature[] lastSequenceFeatures; int sfSize; @@ -268,10 +243,8 @@ public class FeatureRenderer extends public synchronized void drawSequence(Graphics g, final SequenceI seq, int start, int end, int y1) { - final SequenceI aseq = (seq.getDatasetSequence() != null) ? seq - .getDatasetSequence() : seq; - if (aseq.getSequenceFeatures() == null - || aseq.getSequenceFeatures().length == 0) + SequenceFeature[] sequenceFeatures = seq.getSequenceFeatures(); + if (sequenceFeatures == null || sequenceFeatures.length == 0) { return; } @@ -284,10 +257,10 @@ public class FeatureRenderer extends updateFeatures(); if (lastSeq == null || seq != lastSeq - || aseq.getSequenceFeatures() != sequenceFeatures) + || sequenceFeatures != lastSequenceFeatures) { lastSeq = seq; - sequenceFeatures = aseq.getSequenceFeatures(); + lastSequenceFeatures = sequenceFeatures; } if (transparency != 1 && g != null) @@ -303,7 +276,7 @@ public class FeatureRenderer extends epos = lastSeq.findPosition(end); } - sfSize = sequenceFeatures.length; + sfSize = lastSequenceFeatures.length; String type; for (int renderIndex = 0; renderIndex < renderOrder.length; renderIndex++) { @@ -318,25 +291,24 @@ public class FeatureRenderer extends // current feature to render for (sfindex = 0; sfindex < sfSize; sfindex++) { - if (!sequenceFeatures[sfindex].type.equals(type)) + final SequenceFeature sequenceFeature = lastSequenceFeatures[sfindex]; + if (!sequenceFeature.type.equals(type)) { continue; } if (featureGroups != null - && sequenceFeatures[sfindex].featureGroup != null - && sequenceFeatures[sfindex].featureGroup.length() != 0 - && featureGroups - .containsKey(sequenceFeatures[sfindex].featureGroup) - && !featureGroups - .get(sequenceFeatures[sfindex].featureGroup) + && sequenceFeature.featureGroup != null + && sequenceFeature.featureGroup.length() != 0 + && featureGroups.containsKey(sequenceFeature.featureGroup) + && !featureGroups.get(sequenceFeature.featureGroup) .booleanValue()) { continue; } if (!offscreenRender - && (sequenceFeatures[sfindex].getBegin() > epos || sequenceFeatures[sfindex] + && (sequenceFeature.getBegin() > epos || sequenceFeature .getEnd() < spos)) { continue; @@ -344,56 +316,51 @@ public class FeatureRenderer extends if (offscreenRender && offscreenImage == null) { - if (sequenceFeatures[sfindex].begin <= start - && sequenceFeatures[sfindex].end >= start) + if (sequenceFeature.begin <= start + && sequenceFeature.end >= start) { // this is passed out to the overview and other sequence renderers // (e.g. molecule viewer) to get displayed colour for rendered // sequence - currentColour = new Integer( - getColour(sequenceFeatures[sfindex]).getRGB()); + currentColour = new Integer(getColour(sequenceFeature).getRGB()); // used to be retreived from av.featuresDisplayed // currentColour = av.featuresDisplayed // .get(sequenceFeatures[sfindex].type); } } - else if (sequenceFeatures[sfindex].type.equals("disulfide bond")) + else if (sequenceFeature.type.equals("disulfide bond")) { - - renderFeature(g, seq, - seq.findIndex(sequenceFeatures[sfindex].begin) - 1, - seq.findIndex(sequenceFeatures[sfindex].begin) - 1, - getColour(sequenceFeatures[sfindex]) + renderFeature(g, seq, seq.findIndex(sequenceFeature.begin) - 1, + seq.findIndex(sequenceFeature.begin) - 1, + getColour(sequenceFeature) // new Color(((Integer) av.featuresDisplayed // .get(sequenceFeatures[sfindex].type)).intValue()) , start, end, y1); - renderFeature(g, seq, - seq.findIndex(sequenceFeatures[sfindex].end) - 1, - seq.findIndex(sequenceFeatures[sfindex].end) - 1, - getColour(sequenceFeatures[sfindex]) + renderFeature(g, seq, seq.findIndex(sequenceFeature.end) - 1, + seq.findIndex(sequenceFeature.end) - 1, + getColour(sequenceFeature) // new Color(((Integer) av.featuresDisplayed // .get(sequenceFeatures[sfindex].type)).intValue()) , start, end, y1); } - else if (showFeature(sequenceFeatures[sfindex])) + else if (showFeature(sequenceFeature)) { if (av_isShowSeqFeatureHeight - && sequenceFeatures[sfindex].score != Float.NaN) + && sequenceFeature.score != Float.NaN) { renderScoreFeature(g, seq, - seq.findIndex(sequenceFeatures[sfindex].begin) - 1, - seq.findIndex(sequenceFeatures[sfindex].end) - 1, - getColour(sequenceFeatures[sfindex]), start, end, y1, - normaliseScore(sequenceFeatures[sfindex])); + seq.findIndex(sequenceFeature.begin) - 1, + seq.findIndex(sequenceFeature.end) - 1, + getColour(sequenceFeature), start, end, y1, + normaliseScore(sequenceFeature)); } else { - renderFeature(g, seq, - seq.findIndex(sequenceFeatures[sfindex].begin) - 1, - seq.findIndex(sequenceFeatures[sfindex].end) - 1, - getColour(sequenceFeatures[sfindex]), start, end, y1); + renderFeature(g, seq, seq.findIndex(sequenceFeature.begin) - 1, + seq.findIndex(sequenceFeature.end) - 1, + getColour(sequenceFeature), start, end, y1); } } diff --git a/src/jalview/schemabinding/version2/Viewport.java b/src/jalview/schemabinding/version2/Viewport.java index 022dca7..7730e5f 100644 --- a/src/jalview/schemabinding/version2/Viewport.java +++ b/src/jalview/schemabinding/version2/Viewport.java @@ -20,11 +20,9 @@ */ package jalview.schemabinding.version2; + //---------------------------------/ + //- Imported classes and packages -/ //---------------------------------/ -//- Imported classes and packages -/ -//---------------------------------/ - -import jalview.util.MessageManager; import org.exolab.castor.xml.Marshaller; import org.exolab.castor.xml.Unmarshaller; @@ -34,2701 +32,2670 @@ import org.exolab.castor.xml.Unmarshaller; * * @version $Revision$ $Date$ */ -public class Viewport implements java.io.Serializable -{ - - // --------------------------/ - // - Class/Member Variables -/ - // --------------------------/ - - /** - * Field _conservationSelected. - */ - private boolean _conservationSelected; - - /** - * keeps track of state for field: _conservationSelected - */ - private boolean _has_conservationSelected; - - /** - * Field _pidSelected. - */ - private boolean _pidSelected; - - /** - * keeps track of state for field: _pidSelected - */ - private boolean _has_pidSelected; - - /** - * Field _bgColour. - */ - private java.lang.String _bgColour; - - /** - * Field _consThreshold. - */ - private int _consThreshold; - - /** - * keeps track of state for field: _consThreshold - */ - private boolean _has_consThreshold; - - /** - * Field _pidThreshold. - */ - private int _pidThreshold; - - /** - * keeps track of state for field: _pidThreshold - */ - private boolean _has_pidThreshold; - - /** - * Field _title. - */ - private java.lang.String _title; - - /** - * Field _showFullId. - */ - private boolean _showFullId; - - /** - * keeps track of state for field: _showFullId - */ - private boolean _has_showFullId; - - /** - * Field _rightAlignIds. - */ - private boolean _rightAlignIds; - - /** - * keeps track of state for field: _rightAlignIds - */ - private boolean _has_rightAlignIds; - - /** - * Field _showText. - */ - private boolean _showText; - - /** - * keeps track of state for field: _showText - */ - private boolean _has_showText; - - /** - * Field _showColourText. - */ - private boolean _showColourText; - - /** - * keeps track of state for field: _showColourText - */ - private boolean _has_showColourText; - - /** - * Field _showUnconserved. - */ - private boolean _showUnconserved = false; - - /** - * keeps track of state for field: _showUnconserved - */ - private boolean _has_showUnconserved; - - /** - * Field _showBoxes. - */ - private boolean _showBoxes; - - /** - * keeps track of state for field: _showBoxes - */ - private boolean _has_showBoxes; - - /** - * Field _wrapAlignment. - */ - private boolean _wrapAlignment; - - /** - * keeps track of state for field: _wrapAlignment - */ - private boolean _has_wrapAlignment; - - /** - * Field _renderGaps. - */ - private boolean _renderGaps; - - /** - * keeps track of state for field: _renderGaps - */ - private boolean _has_renderGaps; - - /** - * Field _showSequenceFeatures. - */ - private boolean _showSequenceFeatures; - - /** - * keeps track of state for field: _showSequenceFeatures - */ - private boolean _has_showSequenceFeatures; - - /** - * Field _showNPfeatureTooltip. - */ - private boolean _showNPfeatureTooltip; - - /** - * keeps track of state for field: _showNPfeatureTooltip - */ - private boolean _has_showNPfeatureTooltip; - - /** - * Field _showDbRefTooltip. - */ - private boolean _showDbRefTooltip; - - /** - * keeps track of state for field: _showDbRefTooltip - */ - private boolean _has_showDbRefTooltip; - - /** - * Field _followHighlight. - */ - private boolean _followHighlight = true; - - /** - * keeps track of state for field: _followHighlight - */ - private boolean _has_followHighlight; - - /** - * Field _followSelection. - */ - private boolean _followSelection = true; - - /** - * keeps track of state for field: _followSelection - */ - private boolean _has_followSelection; - - /** - * Field _showAnnotation. - */ - private boolean _showAnnotation; - - /** - * keeps track of state for field: _showAnnotation - */ - private boolean _has_showAnnotation; - - /** - * Field _centreColumnLabels. - */ - private boolean _centreColumnLabels = false; - - /** - * keeps track of state for field: _centreColumnLabels - */ - private boolean _has_centreColumnLabels; - - /** - * Field _showGroupConservation. - */ - private boolean _showGroupConservation = false; - - /** - * keeps track of state for field: _showGroupConservation - */ - private boolean _has_showGroupConservation; - - /** - * Field _showGroupConsensus. - */ - private boolean _showGroupConsensus = false; - - /** - * keeps track of state for field: _showGroupConsensus - */ - private boolean _has_showGroupConsensus; - - /** - * Field _showConsensusHistogram. - */ - private boolean _showConsensusHistogram = true; - - /** - * keeps track of state for field: _showConsensusHistogram - */ - private boolean _has_showConsensusHistogram; - - /** - * Field _showSequenceLogo. - */ - private boolean _showSequenceLogo = false; - - /** - * keeps track of state for field: _showSequenceLogo - */ - private boolean _has_showSequenceLogo; - - /** - * Field _normaliseSequenceLogo. - */ - private boolean _normaliseSequenceLogo = false; - - /** - * keeps track of state for field: _normaliseSequenceLogo - */ - private boolean _has_normaliseSequenceLogo; - - /** - * Field _ignoreGapsinConsensus. - */ - private boolean _ignoreGapsinConsensus = true; - - /** - * keeps track of state for field: _ignoreGapsinConsensus - */ - private boolean _has_ignoreGapsinConsensus; - - /** - * Field _startRes. - */ - private int _startRes; - - /** - * keeps track of state for field: _startRes - */ - private boolean _has_startRes; - - /** - * Field _startSeq. - */ - private int _startSeq; - - /** - * keeps track of state for field: _startSeq - */ - private boolean _has_startSeq; - - /** - * Field _fontName. - */ - private java.lang.String _fontName; - - /** - * Field _fontSize. - */ - private int _fontSize; - - /** - * keeps track of state for field: _fontSize - */ - private boolean _has_fontSize; - - /** - * Field _fontStyle. - */ - private int _fontStyle; - - /** - * keeps track of state for field: _fontStyle - */ - private boolean _has_fontStyle; - - /** - * Field _viewName. - */ - private java.lang.String _viewName; - - /** - * Field _sequenceSetId. - */ - private java.lang.String _sequenceSetId; - - /** - * Field _gatheredViews. - */ - private boolean _gatheredViews; - - /** - * keeps track of state for field: _gatheredViews - */ - private boolean _has_gatheredViews; - - /** - * Field _textCol1. - */ - private int _textCol1; - - /** - * keeps track of state for field: _textCol1 - */ - private boolean _has_textCol1; - - /** - * Field _textCol2. - */ - private int _textCol2; - - /** - * keeps track of state for field: _textCol2 - */ - private boolean _has_textCol2; - - /** - * Field _textColThreshold. - */ - private int _textColThreshold; - - /** - * keeps track of state for field: _textColThreshold - */ - private boolean _has_textColThreshold; - - /** - * unique id used by jalview to synchronize between stored and instantiated - * views - * - */ - private java.lang.String _id; - - /** - * Field _width. - */ - private int _width; - - /** - * keeps track of state for field: _width - */ - private boolean _has_width; - - /** - * Field _height. - */ - private int _height; - - /** - * keeps track of state for field: _height - */ - private boolean _has_height; - - /** - * Field _xpos. - */ - private int _xpos; - - /** - * keeps track of state for field: _xpos - */ - private boolean _has_xpos; - - /** - * Field _ypos. - */ - private int _ypos; - - /** - * keeps track of state for field: _ypos - */ - private boolean _has_ypos; - - /** - * Field _annotationColours. - */ - private jalview.schemabinding.version2.AnnotationColours _annotationColours; - - /** - * Field _hiddenColumnsList. - */ - private java.util.Vector _hiddenColumnsList; - - /** - * Field _calcIdParamList. - */ - private java.util.Vector _calcIdParamList; - - // ----------------/ - // - Constructors -/ - // ----------------/ - - public Viewport() - { - super(); - this._hiddenColumnsList = new java.util.Vector(); - this._calcIdParamList = new java.util.Vector(); - } - - // -----------/ - // - Methods -/ - // -----------/ - - /** - * - * - * @param vCalcIdParam - * @throws java.lang.IndexOutOfBoundsException - * if the index given is outside the bounds of the collection - */ - public void addCalcIdParam( - final jalview.schemabinding.version2.CalcIdParam vCalcIdParam) - throws java.lang.IndexOutOfBoundsException - { - this._calcIdParamList.addElement(vCalcIdParam); - } - - /** - * - * - * @param index - * @param vCalcIdParam - * @throws java.lang.IndexOutOfBoundsException - * if the index given is outside the bounds of the collection - */ - public void addCalcIdParam(final int index, - final jalview.schemabinding.version2.CalcIdParam vCalcIdParam) - throws java.lang.IndexOutOfBoundsException - { - this._calcIdParamList.add(index, vCalcIdParam); - } - - /** - * - * - * @param vHiddenColumns - * @throws java.lang.IndexOutOfBoundsException - * if the index given is outside the bounds of the collection - */ - public void addHiddenColumns( - final jalview.schemabinding.version2.HiddenColumns vHiddenColumns) - throws java.lang.IndexOutOfBoundsException - { - this._hiddenColumnsList.addElement(vHiddenColumns); - } - - /** - * - * - * @param index - * @param vHiddenColumns - * @throws java.lang.IndexOutOfBoundsException - * if the index given is outside the bounds of the collection - */ - public void addHiddenColumns(final int index, - final jalview.schemabinding.version2.HiddenColumns vHiddenColumns) - throws java.lang.IndexOutOfBoundsException - { - this._hiddenColumnsList.add(index, vHiddenColumns); - } - - /** - */ - public void deleteCentreColumnLabels() - { - this._has_centreColumnLabels = false; - } - - /** - */ - public void deleteConsThreshold() - { - this._has_consThreshold = false; - } - - /** - */ - public void deleteConservationSelected() - { - this._has_conservationSelected = false; - } - - /** - */ - public void deleteFollowHighlight() - { - this._has_followHighlight = false; - } - - /** - */ - public void deleteFollowSelection() - { - this._has_followSelection = false; - } - - /** - */ - public void deleteFontSize() - { - this._has_fontSize = false; - } - - /** - */ - public void deleteFontStyle() - { - this._has_fontStyle = false; - } - - /** - */ - public void deleteGatheredViews() - { - this._has_gatheredViews = false; - } - - /** - */ - public void deleteHeight() - { - this._has_height = false; - } +public class Viewport implements java.io.Serializable { + + + //--------------------------/ + //- Class/Member Variables -/ + //--------------------------/ + + /** + * Field _conservationSelected. + */ + private boolean _conservationSelected; + + /** + * keeps track of state for field: _conservationSelected + */ + private boolean _has_conservationSelected; + + /** + * Field _pidSelected. + */ + private boolean _pidSelected; + + /** + * keeps track of state for field: _pidSelected + */ + private boolean _has_pidSelected; + + /** + * Field _bgColour. + */ + private java.lang.String _bgColour; + + /** + * Field _consThreshold. + */ + private int _consThreshold; + + /** + * keeps track of state for field: _consThreshold + */ + private boolean _has_consThreshold; + + /** + * Field _pidThreshold. + */ + private int _pidThreshold; + + /** + * keeps track of state for field: _pidThreshold + */ + private boolean _has_pidThreshold; + + /** + * Field _title. + */ + private java.lang.String _title; + + /** + * Field _showFullId. + */ + private boolean _showFullId; + + /** + * keeps track of state for field: _showFullId + */ + private boolean _has_showFullId; + + /** + * Field _rightAlignIds. + */ + private boolean _rightAlignIds; + + /** + * keeps track of state for field: _rightAlignIds + */ + private boolean _has_rightAlignIds; + + /** + * Field _showText. + */ + private boolean _showText; + + /** + * keeps track of state for field: _showText + */ + private boolean _has_showText; + + /** + * Field _showColourText. + */ + private boolean _showColourText; + + /** + * keeps track of state for field: _showColourText + */ + private boolean _has_showColourText; + + /** + * Field _showUnconserved. + */ + private boolean _showUnconserved = false; + + /** + * keeps track of state for field: _showUnconserved + */ + private boolean _has_showUnconserved; + + /** + * Field _showBoxes. + */ + private boolean _showBoxes; + + /** + * keeps track of state for field: _showBoxes + */ + private boolean _has_showBoxes; + + /** + * Field _wrapAlignment. + */ + private boolean _wrapAlignment; + + /** + * keeps track of state for field: _wrapAlignment + */ + private boolean _has_wrapAlignment; + + /** + * Field _renderGaps. + */ + private boolean _renderGaps; + + /** + * keeps track of state for field: _renderGaps + */ + private boolean _has_renderGaps; + + /** + * Field _showSequenceFeatures. + */ + private boolean _showSequenceFeatures; + + /** + * keeps track of state for field: _showSequenceFeatures + */ + private boolean _has_showSequenceFeatures; + + /** + * Field _showNPfeatureTooltip. + */ + private boolean _showNPfeatureTooltip; + + /** + * keeps track of state for field: _showNPfeatureTooltip + */ + private boolean _has_showNPfeatureTooltip; + + /** + * Field _showDbRefTooltip. + */ + private boolean _showDbRefTooltip; + + /** + * keeps track of state for field: _showDbRefTooltip + */ + private boolean _has_showDbRefTooltip; + + /** + * Field _followHighlight. + */ + private boolean _followHighlight = true; + + /** + * keeps track of state for field: _followHighlight + */ + private boolean _has_followHighlight; + + /** + * Field _followSelection. + */ + private boolean _followSelection = true; + + /** + * keeps track of state for field: _followSelection + */ + private boolean _has_followSelection; + + /** + * Field _showAnnotation. + */ + private boolean _showAnnotation; + + /** + * keeps track of state for field: _showAnnotation + */ + private boolean _has_showAnnotation; + + /** + * Field _centreColumnLabels. + */ + private boolean _centreColumnLabels = false; + + /** + * keeps track of state for field: _centreColumnLabels + */ + private boolean _has_centreColumnLabels; + + /** + * Field _showGroupConservation. + */ + private boolean _showGroupConservation = false; + + /** + * keeps track of state for field: _showGroupConservation + */ + private boolean _has_showGroupConservation; + + /** + * Field _showGroupConsensus. + */ + private boolean _showGroupConsensus = false; + + /** + * keeps track of state for field: _showGroupConsensus + */ + private boolean _has_showGroupConsensus; + + /** + * Field _showConsensusHistogram. + */ + private boolean _showConsensusHistogram = true; + + /** + * keeps track of state for field: _showConsensusHistogram + */ + private boolean _has_showConsensusHistogram; + + /** + * Field _showSequenceLogo. + */ + private boolean _showSequenceLogo = false; + + /** + * keeps track of state for field: _showSequenceLogo + */ + private boolean _has_showSequenceLogo; + + /** + * Field _normaliseSequenceLogo. + */ + private boolean _normaliseSequenceLogo = false; + + /** + * keeps track of state for field: _normaliseSequenceLogo + */ + private boolean _has_normaliseSequenceLogo; + + /** + * Field _ignoreGapsinConsensus. + */ + private boolean _ignoreGapsinConsensus = true; + + /** + * keeps track of state for field: _ignoreGapsinConsensus + */ + private boolean _has_ignoreGapsinConsensus; + + /** + * Field _startRes. + */ + private int _startRes; + + /** + * keeps track of state for field: _startRes + */ + private boolean _has_startRes; + + /** + * Field _startSeq. + */ + private int _startSeq; + + /** + * keeps track of state for field: _startSeq + */ + private boolean _has_startSeq; + + /** + * Field _fontName. + */ + private java.lang.String _fontName; + + /** + * Field _fontSize. + */ + private int _fontSize; + + /** + * keeps track of state for field: _fontSize + */ + private boolean _has_fontSize; + + /** + * Field _fontStyle. + */ + private int _fontStyle; + + /** + * keeps track of state for field: _fontStyle + */ + private boolean _has_fontStyle; + + /** + * Field _viewName. + */ + private java.lang.String _viewName; - /** + /** + * Field _sequenceSetId. */ - public void deleteIgnoreGapsinConsensus() - { - this._has_ignoreGapsinConsensus = false; - } + private java.lang.String _sequenceSetId; - /** + /** + * Field _gatheredViews. */ - public void deleteNormaliseSequenceLogo() - { - this._has_normaliseSequenceLogo = false; - } + private boolean _gatheredViews; - /** + /** + * keeps track of state for field: _gatheredViews */ - public void deletePidSelected() - { - this._has_pidSelected = false; - } + private boolean _has_gatheredViews; - /** + /** + * Field _textCol1. */ - public void deletePidThreshold() - { - this._has_pidThreshold = false; - } + private int _textCol1; - /** + /** + * keeps track of state for field: _textCol1 */ - public void deleteRenderGaps() - { - this._has_renderGaps = false; - } + private boolean _has_textCol1; - /** + /** + * Field _textCol2. */ - public void deleteRightAlignIds() - { - this._has_rightAlignIds = false; - } + private int _textCol2; - /** + /** + * keeps track of state for field: _textCol2 */ - public void deleteShowAnnotation() - { - this._has_showAnnotation = false; - } + private boolean _has_textCol2; - /** + /** + * Field _textColThreshold. */ - public void deleteShowBoxes() - { - this._has_showBoxes = false; - } + private int _textColThreshold; - /** + /** + * keeps track of state for field: _textColThreshold */ - public void deleteShowColourText() - { - this._has_showColourText = false; - } + private boolean _has_textColThreshold; - /** + /** + * unique id used by jalview to + * synchronize between stored and + * instantiated views + * */ - public void deleteShowConsensusHistogram() - { - this._has_showConsensusHistogram = false; - } + private java.lang.String _id; - /** + /** + * The viewport id of this viewport's (cdna/protein) coding + * complement, if any + * */ - public void deleteShowDbRefTooltip() - { - this._has_showDbRefTooltip = false; - } + private java.lang.String _complementId; - /** + /** + * Field _width. */ - public void deleteShowFullId() - { - this._has_showFullId = false; - } + private int _width; - /** + /** + * keeps track of state for field: _width */ - public void deleteShowGroupConsensus() - { - this._has_showGroupConsensus = false; - } + private boolean _has_width; - /** + /** + * Field _height. */ - public void deleteShowGroupConservation() - { - this._has_showGroupConservation = false; - } + private int _height; - /** + /** + * keeps track of state for field: _height */ - public void deleteShowNPfeatureTooltip() - { - this._has_showNPfeatureTooltip = false; - } + private boolean _has_height; - /** + /** + * Field _xpos. */ - public void deleteShowSequenceFeatures() - { - this._has_showSequenceFeatures = false; - } + private int _xpos; - /** + /** + * keeps track of state for field: _xpos */ - public void deleteShowSequenceLogo() - { - this._has_showSequenceLogo = false; - } + private boolean _has_xpos; - /** + /** + * Field _ypos. */ - public void deleteShowText() - { - this._has_showText = false; - } + private int _ypos; - /** + /** + * keeps track of state for field: _ypos */ - public void deleteShowUnconserved() - { - this._has_showUnconserved = false; - } + private boolean _has_ypos; - /** + /** + * Field _annotationColours. */ - public void deleteStartRes() - { - this._has_startRes = false; - } - - /** - */ - public void deleteStartSeq() - { - this._has_startSeq = false; - } - - /** - */ - public void deleteTextCol1() - { - this._has_textCol1 = false; - } - - /** - */ - public void deleteTextCol2() - { - this._has_textCol2 = false; - } - - /** - */ - public void deleteTextColThreshold() - { - this._has_textColThreshold = false; - } - - /** - */ - public void deleteWidth() - { - this._has_width = false; - } - - /** - */ - public void deleteWrapAlignment() - { - this._has_wrapAlignment = false; - } - - /** - */ - public void deleteXpos() - { - this._has_xpos = false; - } - - /** - */ - public void deleteYpos() - { - this._has_ypos = false; - } - - /** - * Method enumerateCalcIdParam. - * - * @return an Enumeration over all jalview.schemabinding.version2.CalcIdParam - * elements - */ - public java.util.Enumeration enumerateCalcIdParam() - { - return this._calcIdParamList.elements(); - } - - /** - * Method enumerateHiddenColumns. - * - * @return an Enumeration over all - * jalview.schemabinding.version2.HiddenColumns elements - */ - public java.util.Enumeration enumerateHiddenColumns() - { - return this._hiddenColumnsList.elements(); - } - - /** - * Returns the value of field 'annotationColours'. - * - * @return the value of field 'AnnotationColours'. - */ - public jalview.schemabinding.version2.AnnotationColours getAnnotationColours() - { - return this._annotationColours; - } - - /** - * Returns the value of field 'bgColour'. - * - * @return the value of field 'BgColour'. - */ - public java.lang.String getBgColour() - { - return this._bgColour; - } - - /** - * Method getCalcIdParam. - * - * @param index - * @throws java.lang.IndexOutOfBoundsException - * if the index given is outside the bounds of the collection - * @return the value of the jalview.schemabinding.version2.CalcIdParam at the - * given index - */ - public jalview.schemabinding.version2.CalcIdParam getCalcIdParam( - final int index) throws java.lang.IndexOutOfBoundsException - { - // check bounds for index - if (index < 0 || index >= this._calcIdParamList.size()) - { - throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{ - "getCalcIdParam", - Integer.valueOf(index).toString(), - Integer.valueOf((this._calcIdParamList.size() - 1)).toString() - })); - } - - return (jalview.schemabinding.version2.CalcIdParam) _calcIdParamList - .get(index); - } - - /** - * Method getCalcIdParam.Returns the contents of the collection in an Array. - *

- * Note: Just in case the collection contents are changing in another thread, - * we pass a 0-length Array of the correct type into the API call. This way we - * know that the Array returned is of exactly the correct length. - * - * @return this collection as an Array - */ - public jalview.schemabinding.version2.CalcIdParam[] getCalcIdParam() - { - jalview.schemabinding.version2.CalcIdParam[] array = new jalview.schemabinding.version2.CalcIdParam[0]; - return (jalview.schemabinding.version2.CalcIdParam[]) this._calcIdParamList - .toArray(array); - } - - /** - * Method getCalcIdParamCount. - * - * @return the size of this collection - */ - public int getCalcIdParamCount() - { - return this._calcIdParamList.size(); - } - - /** - * Returns the value of field 'centreColumnLabels'. - * - * @return the value of field 'CentreColumnLabels'. - */ - public boolean getCentreColumnLabels() - { - return this._centreColumnLabels; - } - - /** - * Returns the value of field 'consThreshold'. - * - * @return the value of field 'ConsThreshold'. - */ - public int getConsThreshold() - { - return this._consThreshold; - } - - /** - * Returns the value of field 'conservationSelected'. - * - * @return the value of field 'ConservationSelected'. - */ - public boolean getConservationSelected() - { - return this._conservationSelected; - } - - /** - * Returns the value of field 'followHighlight'. - * - * @return the value of field 'FollowHighlight'. - */ - public boolean getFollowHighlight() - { - return this._followHighlight; - } - - /** - * Returns the value of field 'followSelection'. - * - * @return the value of field 'FollowSelection'. - */ - public boolean getFollowSelection() - { - return this._followSelection; - } - - /** - * Returns the value of field 'fontName'. - * - * @return the value of field 'FontName'. - */ - public java.lang.String getFontName() - { - return this._fontName; - } - - /** - * Returns the value of field 'fontSize'. - * - * @return the value of field 'FontSize'. - */ - public int getFontSize() - { - return this._fontSize; - } - - /** - * Returns the value of field 'fontStyle'. - * - * @return the value of field 'FontStyle'. - */ - public int getFontStyle() - { - return this._fontStyle; - } - - /** - * Returns the value of field 'gatheredViews'. - * - * @return the value of field 'GatheredViews'. - */ - public boolean getGatheredViews() - { - return this._gatheredViews; - } - - /** - * Returns the value of field 'height'. - * - * @return the value of field 'Height'. - */ - public int getHeight() - { - return this._height; - } - - /** - * Method getHiddenColumns. - * - * @param index - * @throws java.lang.IndexOutOfBoundsException - * if the index given is outside the bounds of the collection - * @return the value of the jalview.schemabinding.version2.HiddenColumns at - * the given index - */ - public jalview.schemabinding.version2.HiddenColumns getHiddenColumns( - final int index) throws java.lang.IndexOutOfBoundsException - { - // check bounds for index - if (index < 0 || index >= this._hiddenColumnsList.size()) - { - throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{ - "getHiddenColumns", - Integer.valueOf(index).toString(), - Integer.valueOf((this._hiddenColumnsList.size() - 1)).toString() - })); - } - - return (jalview.schemabinding.version2.HiddenColumns) _hiddenColumnsList - .get(index); - } - - /** - * Method getHiddenColumns.Returns the contents of the collection in an Array. - *

- * Note: Just in case the collection contents are changing in another thread, - * we pass a 0-length Array of the correct type into the API call. This way we - * know that the Array returned is of exactly the correct length. - * - * @return this collection as an Array - */ - public jalview.schemabinding.version2.HiddenColumns[] getHiddenColumns() - { - jalview.schemabinding.version2.HiddenColumns[] array = new jalview.schemabinding.version2.HiddenColumns[0]; - return (jalview.schemabinding.version2.HiddenColumns[]) this._hiddenColumnsList - .toArray(array); - } - - /** - * Method getHiddenColumnsCount. - * - * @return the size of this collection - */ - public int getHiddenColumnsCount() - { - return this._hiddenColumnsList.size(); - } - - /** - * Returns the value of field 'id'. The field 'id' has the following - * description: unique id used by jalview to synchronize between stored and - * instantiated views - * - * - * @return the value of field 'Id'. - */ - public java.lang.String getId() - { - return this._id; - } - - /** - * Returns the value of field 'ignoreGapsinConsensus'. - * - * @return the value of field 'IgnoreGapsinConsensus'. - */ - public boolean getIgnoreGapsinConsensus() - { - return this._ignoreGapsinConsensus; - } - - /** - * Returns the value of field 'normaliseSequenceLogo'. - * - * @return the value of field 'NormaliseSequenceLogo'. - */ - public boolean getNormaliseSequenceLogo() - { - return this._normaliseSequenceLogo; - } - - /** - * Returns the value of field 'pidSelected'. - * - * @return the value of field 'PidSelected'. - */ - public boolean getPidSelected() - { - return this._pidSelected; - } - - /** - * Returns the value of field 'pidThreshold'. - * - * @return the value of field 'PidThreshold'. - */ - public int getPidThreshold() - { - return this._pidThreshold; - } - - /** - * Returns the value of field 'renderGaps'. - * - * @return the value of field 'RenderGaps'. - */ - public boolean getRenderGaps() - { - return this._renderGaps; - } - - /** - * Returns the value of field 'rightAlignIds'. - * - * @return the value of field 'RightAlignIds'. - */ - public boolean getRightAlignIds() - { - return this._rightAlignIds; - } - - /** - * Returns the value of field 'sequenceSetId'. - * - * @return the value of field 'SequenceSetId'. - */ - public java.lang.String getSequenceSetId() - { - return this._sequenceSetId; - } - - /** - * Returns the value of field 'showAnnotation'. - * - * @return the value of field 'ShowAnnotation'. - */ - public boolean getShowAnnotation() - { - return this._showAnnotation; - } - - /** - * Returns the value of field 'showBoxes'. - * - * @return the value of field 'ShowBoxes'. - */ - public boolean getShowBoxes() - { - return this._showBoxes; - } - - /** - * Returns the value of field 'showColourText'. - * - * @return the value of field 'ShowColourText'. - */ - public boolean getShowColourText() - { - return this._showColourText; - } - - /** - * Returns the value of field 'showConsensusHistogram'. - * - * @return the value of field 'ShowConsensusHistogram'. - */ - public boolean getShowConsensusHistogram() - { - return this._showConsensusHistogram; - } - - /** - * Returns the value of field 'showDbRefTooltip'. - * - * @return the value of field 'ShowDbRefTooltip'. - */ - public boolean getShowDbRefTooltip() - { - return this._showDbRefTooltip; - } - - /** - * Returns the value of field 'showFullId'. - * - * @return the value of field 'ShowFullId'. - */ - public boolean getShowFullId() - { - return this._showFullId; - } - - /** - * Returns the value of field 'showGroupConsensus'. - * - * @return the value of field 'ShowGroupConsensus'. - */ - public boolean getShowGroupConsensus() - { - return this._showGroupConsensus; - } - - /** - * Returns the value of field 'showGroupConservation'. - * - * @return the value of field 'ShowGroupConservation'. - */ - public boolean getShowGroupConservation() - { - return this._showGroupConservation; - } - - /** - * Returns the value of field 'showNPfeatureTooltip'. - * - * @return the value of field 'ShowNPfeatureTooltip'. - */ - public boolean getShowNPfeatureTooltip() - { - return this._showNPfeatureTooltip; - } - - /** - * Returns the value of field 'showSequenceFeatures'. - * - * @return the value of field 'ShowSequenceFeatures'. - */ - public boolean getShowSequenceFeatures() - { - return this._showSequenceFeatures; - } - - /** - * Returns the value of field 'showSequenceLogo'. - * - * @return the value of field 'ShowSequenceLogo'. - */ - public boolean getShowSequenceLogo() - { - return this._showSequenceLogo; - } - - /** - * Returns the value of field 'showText'. - * - * @return the value of field 'ShowText'. - */ - public boolean getShowText() - { - return this._showText; - } - - /** - * Returns the value of field 'showUnconserved'. - * - * @return the value of field 'ShowUnconserved'. - */ - public boolean getShowUnconserved() - { - return this._showUnconserved; - } - - /** - * Returns the value of field 'startRes'. - * - * @return the value of field 'StartRes'. - */ - public int getStartRes() - { - return this._startRes; - } - - /** - * Returns the value of field 'startSeq'. - * - * @return the value of field 'StartSeq'. - */ - public int getStartSeq() - { - return this._startSeq; - } - - /** - * Returns the value of field 'textCol1'. - * - * @return the value of field 'TextCol1'. - */ - public int getTextCol1() - { - return this._textCol1; - } - - /** - * Returns the value of field 'textCol2'. - * - * @return the value of field 'TextCol2'. - */ - public int getTextCol2() - { - return this._textCol2; - } - - /** - * Returns the value of field 'textColThreshold'. - * - * @return the value of field 'TextColThreshold'. - */ - public int getTextColThreshold() - { - return this._textColThreshold; - } - - /** - * Returns the value of field 'title'. - * - * @return the value of field 'Title'. - */ - public java.lang.String getTitle() - { - return this._title; - } - - /** - * Returns the value of field 'viewName'. - * - * @return the value of field 'ViewName'. - */ - public java.lang.String getViewName() - { - return this._viewName; - } - - /** - * Returns the value of field 'width'. - * - * @return the value of field 'Width'. - */ - public int getWidth() - { - return this._width; - } - - /** - * Returns the value of field 'wrapAlignment'. - * - * @return the value of field 'WrapAlignment'. - */ - public boolean getWrapAlignment() - { - return this._wrapAlignment; - } - - /** - * Returns the value of field 'xpos'. - * - * @return the value of field 'Xpos'. - */ - public int getXpos() - { - return this._xpos; - } - - /** - * Returns the value of field 'ypos'. - * - * @return the value of field 'Ypos'. - */ - public int getYpos() - { - return this._ypos; - } - - /** - * Method hasCentreColumnLabels. - * - * @return true if at least one CentreColumnLabels has been adde - */ - public boolean hasCentreColumnLabels() - { - return this._has_centreColumnLabels; - } - - /** - * Method hasConsThreshold. - * - * @return true if at least one ConsThreshold has been added - */ - public boolean hasConsThreshold() - { - return this._has_consThreshold; - } - - /** - * Method hasConservationSelected. - * - * @return true if at least one ConservationSelected has been added - */ - public boolean hasConservationSelected() - { - return this._has_conservationSelected; - } - - /** - * Method hasFollowHighlight. - * - * @return true if at least one FollowHighlight has been added - */ - public boolean hasFollowHighlight() - { - return this._has_followHighlight; - } - - /** - * Method hasFollowSelection. - * - * @return true if at least one FollowSelection has been added - */ - public boolean hasFollowSelection() - { - return this._has_followSelection; - } - - /** - * Method hasFontSize. - * - * @return true if at least one FontSize has been added - */ - public boolean hasFontSize() - { - return this._has_fontSize; - } - - /** - * Method hasFontStyle. - * - * @return true if at least one FontStyle has been added - */ - public boolean hasFontStyle() - { - return this._has_fontStyle; - } - - /** - * Method hasGatheredViews. - * - * @return true if at least one GatheredViews has been added - */ - public boolean hasGatheredViews() - { - return this._has_gatheredViews; - } - - /** - * Method hasHeight. - * - * @return true if at least one Height has been added - */ - public boolean hasHeight() - { - return this._has_height; - } - - /** - * Method hasIgnoreGapsinConsensus. - * - * @return true if at least one IgnoreGapsinConsensus has been added - */ - public boolean hasIgnoreGapsinConsensus() - { - return this._has_ignoreGapsinConsensus; - } - - /** - * Method hasNormaliseSequenceLogo. - * - * @return true if at least one NormaliseSequenceLogo has been added - */ - public boolean hasNormaliseSequenceLogo() - { - return this._has_normaliseSequenceLogo; - } - - /** - * Method hasPidSelected. - * - * @return true if at least one PidSelected has been added - */ - public boolean hasPidSelected() - { - return this._has_pidSelected; - } - - /** - * Method hasPidThreshold. - * - * @return true if at least one PidThreshold has been added - */ - public boolean hasPidThreshold() - { - return this._has_pidThreshold; - } - - /** - * Method hasRenderGaps. - * - * @return true if at least one RenderGaps has been added - */ - public boolean hasRenderGaps() - { - return this._has_renderGaps; - } - - /** - * Method hasRightAlignIds. - * - * @return true if at least one RightAlignIds has been added - */ - public boolean hasRightAlignIds() - { - return this._has_rightAlignIds; - } - - /** - * Method hasShowAnnotation. - * - * @return true if at least one ShowAnnotation has been added - */ - public boolean hasShowAnnotation() - { - return this._has_showAnnotation; - } - - /** - * Method hasShowBoxes. - * - * @return true if at least one ShowBoxes has been added - */ - public boolean hasShowBoxes() - { - return this._has_showBoxes; - } - - /** - * Method hasShowColourText. - * - * @return true if at least one ShowColourText has been added - */ - public boolean hasShowColourText() - { - return this._has_showColourText; - } - - /** - * Method hasShowConsensusHistogram. - * - * @return true if at least one ShowConsensusHistogram has been added - */ - public boolean hasShowConsensusHistogram() - { - return this._has_showConsensusHistogram; - } - - /** - * Method hasShowDbRefTooltip. - * - * @return true if at least one ShowDbRefTooltip has been added - */ - public boolean hasShowDbRefTooltip() - { - return this._has_showDbRefTooltip; - } - - /** - * Method hasShowFullId. - * - * @return true if at least one ShowFullId has been added - */ - public boolean hasShowFullId() - { - return this._has_showFullId; - } - - /** - * Method hasShowGroupConsensus. - * - * @return true if at least one ShowGroupConsensus has been adde - */ - public boolean hasShowGroupConsensus() - { - return this._has_showGroupConsensus; - } - - /** - * Method hasShowGroupConservation. - * - * @return true if at least one ShowGroupConservation has been added - */ - public boolean hasShowGroupConservation() - { - return this._has_showGroupConservation; - } - - /** - * Method hasShowNPfeatureTooltip. - * - * @return true if at least one ShowNPfeatureTooltip has been added - */ - public boolean hasShowNPfeatureTooltip() - { - return this._has_showNPfeatureTooltip; - } - - /** - * Method hasShowSequenceFeatures. - * - * @return true if at least one ShowSequenceFeatures has been added - */ - public boolean hasShowSequenceFeatures() - { - return this._has_showSequenceFeatures; - } - - /** - * Method hasShowSequenceLogo. - * - * @return true if at least one ShowSequenceLogo has been added - */ - public boolean hasShowSequenceLogo() - { - return this._has_showSequenceLogo; - } - - /** - * Method hasShowText. - * - * @return true if at least one ShowText has been added - */ - public boolean hasShowText() - { - return this._has_showText; - } - - /** - * Method hasShowUnconserved. - * - * @return true if at least one ShowUnconserved has been added - */ - public boolean hasShowUnconserved() - { - return this._has_showUnconserved; - } - - /** - * Method hasStartRes. - * - * @return true if at least one StartRes has been added - */ - public boolean hasStartRes() - { - return this._has_startRes; - } - - /** - * Method hasStartSeq. - * - * @return true if at least one StartSeq has been added - */ - public boolean hasStartSeq() - { - return this._has_startSeq; - } - - /** - * Method hasTextCol1. - * - * @return true if at least one TextCol1 has been added - */ - public boolean hasTextCol1() - { - return this._has_textCol1; - } - - /** - * Method hasTextCol2. - * - * @return true if at least one TextCol2 has been added - */ - public boolean hasTextCol2() - { - return this._has_textCol2; - } - - /** - * Method hasTextColThreshold. - * - * @return true if at least one TextColThreshold has been added - */ - public boolean hasTextColThreshold() - { - return this._has_textColThreshold; - } - - /** - * Method hasWidth. - * - * @return true if at least one Width has been added - */ - public boolean hasWidth() - { - return this._has_width; - } - - /** - * Method hasWrapAlignment. - * - * @return true if at least one WrapAlignment has been added - */ - public boolean hasWrapAlignment() - { - return this._has_wrapAlignment; - } - - /** - * Method hasXpos. - * - * @return true if at least one Xpos has been added - */ - public boolean hasXpos() - { - return this._has_xpos; - } - - /** - * Method hasYpos. - * - * @return true if at least one Ypos has been added - */ - public boolean hasYpos() - { - return this._has_ypos; - } - - /** - * Returns the value of field 'centreColumnLabels'. - * - * @return the value of field 'CentreColumnLabels'. - */ - public boolean isCentreColumnLabels() - { - return this._centreColumnLabels; - } - - /** - * Returns the value of field 'conservationSelected'. - * - * @return the value of field 'ConservationSelected'. - */ - public boolean isConservationSelected() - { - return this._conservationSelected; - } - - /** - * Returns the value of field 'followHighlight'. - * - * @return the value of field 'FollowHighlight'. - */ - public boolean isFollowHighlight() - { - return this._followHighlight; - } - - /** - * Returns the value of field 'followSelection'. - * - * @return the value of field 'FollowSelection'. - */ - public boolean isFollowSelection() - { - return this._followSelection; - } - - /** - * Returns the value of field 'gatheredViews'. - * - * @return the value of field 'GatheredViews'. - */ - public boolean isGatheredViews() - { - return this._gatheredViews; - } - - /** - * Returns the value of field 'ignoreGapsinConsensus'. - * - * @return the value of field 'IgnoreGapsinConsensus'. - */ - public boolean isIgnoreGapsinConsensus() - { - return this._ignoreGapsinConsensus; - } - - /** - * Returns the value of field 'normaliseSequenceLogo'. - * - * @return the value of field 'NormaliseSequenceLogo'. - */ - public boolean isNormaliseSequenceLogo() - { - return this._normaliseSequenceLogo; - } - - /** - * Returns the value of field 'pidSelected'. - * - * @return the value of field 'PidSelected'. - */ - public boolean isPidSelected() - { - return this._pidSelected; - } - - /** - * Returns the value of field 'renderGaps'. - * - * @return the value of field 'RenderGaps'. - */ - public boolean isRenderGaps() - { - return this._renderGaps; - } - - /** - * Returns the value of field 'rightAlignIds'. - * - * @return the value of field 'RightAlignIds'. - */ - public boolean isRightAlignIds() - { - return this._rightAlignIds; - } - - /** - * Returns the value of field 'showAnnotation'. - * - * @return the value of field 'ShowAnnotation'. - */ - public boolean isShowAnnotation() - { - return this._showAnnotation; - } - - /** - * Returns the value of field 'showBoxes'. - * - * @return the value of field 'ShowBoxes'. - */ - public boolean isShowBoxes() - { - return this._showBoxes; - } - - /** - * Returns the value of field 'showColourText'. - * - * @return the value of field 'ShowColourText'. - */ - public boolean isShowColourText() - { - return this._showColourText; - } - - /** - * Returns the value of field 'showConsensusHistogram'. - * - * @return the value of field 'ShowConsensusHistogram'. - */ - public boolean isShowConsensusHistogram() - { - return this._showConsensusHistogram; - } - - /** - * Returns the value of field 'showDbRefTooltip'. - * - * @return the value of field 'ShowDbRefTooltip'. - */ - public boolean isShowDbRefTooltip() - { - return this._showDbRefTooltip; - } - - /** - * Returns the value of field 'showFullId'. - * - * @return the value of field 'ShowFullId'. - */ - public boolean isShowFullId() - { - return this._showFullId; - } - - /** - * Returns the value of field 'showGroupConsensus'. - * - * @return the value of field 'ShowGroupConsensus'. - */ - public boolean isShowGroupConsensus() - { - return this._showGroupConsensus; - } - - /** - * Returns the value of field 'showGroupConservation'. - * - * @return the value of field 'ShowGroupConservation'. - */ - public boolean isShowGroupConservation() - { - return this._showGroupConservation; - } - - /** - * Returns the value of field 'showNPfeatureTooltip'. - * - * @return the value of field 'ShowNPfeatureTooltip'. - */ - public boolean isShowNPfeatureTooltip() - { - return this._showNPfeatureTooltip; - } - - /** - * Returns the value of field 'showSequenceFeatures'. - * - * @return the value of field 'ShowSequenceFeatures'. - */ - public boolean isShowSequenceFeatures() - { - return this._showSequenceFeatures; - } - - /** - * Returns the value of field 'showSequenceLogo'. - * - * @return the value of field 'ShowSequenceLogo'. - */ - public boolean isShowSequenceLogo() - { - return this._showSequenceLogo; - } - - /** - * Returns the value of field 'showText'. - * - * @return the value of field 'ShowText'. - */ - public boolean isShowText() - { - return this._showText; - } - - /** - * Returns the value of field 'showUnconserved'. - * - * @return the value of field 'ShowUnconserved'. - */ - public boolean isShowUnconserved() - { - return this._showUnconserved; - } - - /** - * Method isValid. - * - * @return true if this object is valid according to the schema - */ - public boolean isValid() - { - try - { - validate(); - } catch (org.exolab.castor.xml.ValidationException vex) - { - return false; - } - return true; - } - - /** - * Returns the value of field 'wrapAlignment'. - * - * @return the value of field 'WrapAlignment'. - */ - public boolean isWrapAlignment() - { - return this._wrapAlignment; - } - - /** - * - * - * @param out - * @throws org.exolab.castor.xml.MarshalException - * if object is null or if any SAXException is thrown during - * marshaling - * @throws org.exolab.castor.xml.ValidationException - * if this object is an invalid instance according to the schema - */ - public void marshal(final java.io.Writer out) - throws org.exolab.castor.xml.MarshalException, - org.exolab.castor.xml.ValidationException - { - Marshaller.marshal(this, out); - } - - /** - * - * - * @param handler - * @throws java.io.IOException - * if an IOException occurs during marshaling - * @throws org.exolab.castor.xml.ValidationException - * if this object is an invalid instance according to the schema - * @throws org.exolab.castor.xml.MarshalException - * if object is null or if any SAXException is thrown during - * marshaling - */ - public void marshal(final org.xml.sax.ContentHandler handler) - throws java.io.IOException, - org.exolab.castor.xml.MarshalException, - org.exolab.castor.xml.ValidationException - { - Marshaller.marshal(this, handler); - } - - /** - */ - public void removeAllCalcIdParam() - { - this._calcIdParamList.clear(); - } - - /** - */ - public void removeAllHiddenColumns() - { - this._hiddenColumnsList.clear(); - } - - /** - * Method removeCalcIdParam. - * - * @param vCalcIdParam - * @return true if the object was removed from the collection. - */ - public boolean removeCalcIdParam( - final jalview.schemabinding.version2.CalcIdParam vCalcIdParam) - { - boolean removed = _calcIdParamList.remove(vCalcIdParam); - return removed; - } - - /** - * Method removeCalcIdParamAt. - * - * @param index - * @return the element removed from the collection - */ - public jalview.schemabinding.version2.CalcIdParam removeCalcIdParamAt( - final int index) - { - java.lang.Object obj = this._calcIdParamList.remove(index); - return (jalview.schemabinding.version2.CalcIdParam) obj; - } - - /** - * Method removeHiddenColumns. - * - * @param vHiddenColumns - * @return true if the object was removed from the collection. - */ - public boolean removeHiddenColumns( - final jalview.schemabinding.version2.HiddenColumns vHiddenColumns) - { - boolean removed = _hiddenColumnsList.remove(vHiddenColumns); - return removed; - } - - /** - * Method removeHiddenColumnsAt. - * - * @param index - * @return the element removed from the collection - */ - public jalview.schemabinding.version2.HiddenColumns removeHiddenColumnsAt( - final int index) - { - java.lang.Object obj = this._hiddenColumnsList.remove(index); - return (jalview.schemabinding.version2.HiddenColumns) obj; - } - - /** - * Sets the value of field 'annotationColours'. - * - * @param annotationColours - * the value of field 'annotationColours'. - */ - public void setAnnotationColours( - final jalview.schemabinding.version2.AnnotationColours annotationColours) - { - this._annotationColours = annotationColours; - } - - /** - * Sets the value of field 'bgColour'. - * - * @param bgColour - * the value of field 'bgColour'. - */ - public void setBgColour(final java.lang.String bgColour) - { - this._bgColour = bgColour; - } - - /** - * - * - * @param index - * @param vCalcIdParam - * @throws java.lang.IndexOutOfBoundsException - * if the index given is outside the bounds of the collection - */ - public void setCalcIdParam(final int index, - final jalview.schemabinding.version2.CalcIdParam vCalcIdParam) - throws java.lang.IndexOutOfBoundsException - { - // check bounds for index - if (index < 0 || index >= this._calcIdParamList.size()) - { - throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{ - "setCalcIdParam", - Integer.valueOf(index).toString(), - Integer.valueOf((this._calcIdParamList.size() - 1)).toString() - })); - } - - this._calcIdParamList.set(index, vCalcIdParam); - } - - /** - * - * - * @param vCalcIdParamArray - */ - public void setCalcIdParam( - final jalview.schemabinding.version2.CalcIdParam[] vCalcIdParamArray) - { - // -- copy array - _calcIdParamList.clear(); - - for (int i = 0; i < vCalcIdParamArray.length; i++) - { - this._calcIdParamList.add(vCalcIdParamArray[i]); - } - } - - /** - * Sets the value of field 'centreColumnLabels'. - * - * @param centreColumnLabels - * the value of field 'centreColumnLabels'. - */ - public void setCentreColumnLabels(final boolean centreColumnLabels) - { - this._centreColumnLabels = centreColumnLabels; - this._has_centreColumnLabels = true; - } - - /** - * Sets the value of field 'consThreshold'. - * - * @param consThreshold - * the value of field 'consThreshold'. - */ - public void setConsThreshold(final int consThreshold) - { - this._consThreshold = consThreshold; - this._has_consThreshold = true; - } - - /** - * Sets the value of field 'conservationSelected'. - * - * @param conservationSelected - * the value of field 'conservationSelected'. - */ - public void setConservationSelected(final boolean conservationSelected) - { - this._conservationSelected = conservationSelected; - this._has_conservationSelected = true; - } - - /** - * Sets the value of field 'followHighlight'. - * - * @param followHighlight - * the value of field 'followHighlight'. - */ - public void setFollowHighlight(final boolean followHighlight) - { - this._followHighlight = followHighlight; - this._has_followHighlight = true; - } - - /** - * Sets the value of field 'followSelection'. - * - * @param followSelection - * the value of field 'followSelection'. - */ - public void setFollowSelection(final boolean followSelection) - { - this._followSelection = followSelection; - this._has_followSelection = true; - } - - /** - * Sets the value of field 'fontName'. - * - * @param fontName - * the value of field 'fontName'. - */ - public void setFontName(final java.lang.String fontName) - { - this._fontName = fontName; - } - - /** - * Sets the value of field 'fontSize'. - * - * @param fontSize - * the value of field 'fontSize'. - */ - public void setFontSize(final int fontSize) - { - this._fontSize = fontSize; - this._has_fontSize = true; - } - - /** - * Sets the value of field 'fontStyle'. - * - * @param fontStyle - * the value of field 'fontStyle'. - */ - public void setFontStyle(final int fontStyle) - { - this._fontStyle = fontStyle; - this._has_fontStyle = true; - } - - /** - * Sets the value of field 'gatheredViews'. - * - * @param gatheredViews - * the value of field 'gatheredViews'. - */ - public void setGatheredViews(final boolean gatheredViews) - { - this._gatheredViews = gatheredViews; - this._has_gatheredViews = true; - } - - /** - * Sets the value of field 'height'. - * - * @param height - * the value of field 'height'. - */ - public void setHeight(final int height) - { - this._height = height; - this._has_height = true; - } - - /** - * - * - * @param index - * @param vHiddenColumns - * @throws java.lang.IndexOutOfBoundsException - * if the index given is outside the bounds of the collection - */ - public void setHiddenColumns(final int index, - final jalview.schemabinding.version2.HiddenColumns vHiddenColumns) - throws java.lang.IndexOutOfBoundsException - { - // check bounds for index - if (index < 0 || index >= this._hiddenColumnsList.size()) - { - throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{ - "setHiddenColumns", - Integer.valueOf(index).toString(), - Integer.valueOf((this._hiddenColumnsList.size() - 1)).toString() - })); - } - - this._hiddenColumnsList.set(index, vHiddenColumns); - } - - /** - * - * - * @param vHiddenColumnsArray - */ - public void setHiddenColumns( - final jalview.schemabinding.version2.HiddenColumns[] vHiddenColumnsArray) - { - // -- copy array - _hiddenColumnsList.clear(); - - for (int i = 0; i < vHiddenColumnsArray.length; i++) - { - this._hiddenColumnsList.add(vHiddenColumnsArray[i]); - } - } - - /** - * Sets the value of field 'id'. The field 'id' has the following description: - * unique id used by jalview to synchronize between stored and instantiated - * views - * - * - * @param id - * the value of field 'id'. - */ - public void setId(final java.lang.String id) - { - this._id = id; - } - - /** - * Sets the value of field 'ignoreGapsinConsensus'. - * - * @param ignoreGapsinConsensus - * the value of field 'ignoreGapsinConsensus'. - */ - public void setIgnoreGapsinConsensus(final boolean ignoreGapsinConsensus) - { - this._ignoreGapsinConsensus = ignoreGapsinConsensus; - this._has_ignoreGapsinConsensus = true; - } - - /** - * Sets the value of field 'normaliseSequenceLogo'. - * - * @param normaliseSequenceLogo - * the value of field 'normaliseSequenceLogo'. - */ - public void setNormaliseSequenceLogo(final boolean normaliseSequenceLogo) - { - this._normaliseSequenceLogo = normaliseSequenceLogo; - this._has_normaliseSequenceLogo = true; - } - - /** - * Sets the value of field 'pidSelected'. - * - * @param pidSelected - * the value of field 'pidSelected'. - */ - public void setPidSelected(final boolean pidSelected) - { - this._pidSelected = pidSelected; - this._has_pidSelected = true; - } - - /** - * Sets the value of field 'pidThreshold'. - * - * @param pidThreshold - * the value of field 'pidThreshold'. - */ - public void setPidThreshold(final int pidThreshold) - { - this._pidThreshold = pidThreshold; - this._has_pidThreshold = true; - } - - /** - * Sets the value of field 'renderGaps'. - * - * @param renderGaps - * the value of field 'renderGaps'. - */ - public void setRenderGaps(final boolean renderGaps) - { - this._renderGaps = renderGaps; - this._has_renderGaps = true; - } - - /** - * Sets the value of field 'rightAlignIds'. - * - * @param rightAlignIds - * the value of field 'rightAlignIds'. - */ - public void setRightAlignIds(final boolean rightAlignIds) - { - this._rightAlignIds = rightAlignIds; - this._has_rightAlignIds = true; - } - - /** - * Sets the value of field 'sequenceSetId'. - * - * @param sequenceSetId - * the value of field 'sequenceSetId'. - */ - public void setSequenceSetId(final java.lang.String sequenceSetId) - { - this._sequenceSetId = sequenceSetId; - } - - /** - * Sets the value of field 'showAnnotation'. - * - * @param showAnnotation - * the value of field 'showAnnotation'. - */ - public void setShowAnnotation(final boolean showAnnotation) - { - this._showAnnotation = showAnnotation; - this._has_showAnnotation = true; - } - - /** - * Sets the value of field 'showBoxes'. - * - * @param showBoxes - * the value of field 'showBoxes'. - */ - public void setShowBoxes(final boolean showBoxes) - { - this._showBoxes = showBoxes; - this._has_showBoxes = true; - } - - /** - * Sets the value of field 'showColourText'. - * - * @param showColourText - * the value of field 'showColourText'. - */ - public void setShowColourText(final boolean showColourText) - { - this._showColourText = showColourText; - this._has_showColourText = true; - } - - /** - * Sets the value of field 'showConsensusHistogram'. - * - * @param showConsensusHistogram - * the value of field 'showConsensusHistogram'. - */ - public void setShowConsensusHistogram(final boolean showConsensusHistogram) - { - this._showConsensusHistogram = showConsensusHistogram; - this._has_showConsensusHistogram = true; - } - - /** - * Sets the value of field 'showDbRefTooltip'. - * - * @param showDbRefTooltip - * the value of field 'showDbRefTooltip' - */ - public void setShowDbRefTooltip(final boolean showDbRefTooltip) - { - this._showDbRefTooltip = showDbRefTooltip; - this._has_showDbRefTooltip = true; - } - - /** - * Sets the value of field 'showFullId'. - * - * @param showFullId - * the value of field 'showFullId'. - */ - public void setShowFullId(final boolean showFullId) - { - this._showFullId = showFullId; - this._has_showFullId = true; - } - - /** - * Sets the value of field 'showGroupConsensus'. - * - * @param showGroupConsensus - * the value of field 'showGroupConsensus'. - */ - public void setShowGroupConsensus(final boolean showGroupConsensus) - { - this._showGroupConsensus = showGroupConsensus; - this._has_showGroupConsensus = true; - } - - /** - * Sets the value of field 'showGroupConservation'. - * - * @param showGroupConservation - * the value of field 'showGroupConservation'. - */ - public void setShowGroupConservation(final boolean showGroupConservation) - { - this._showGroupConservation = showGroupConservation; - this._has_showGroupConservation = true; - } - - /** - * Sets the value of field 'showNPfeatureTooltip'. - * - * @param showNPfeatureTooltip - * the value of field 'showNPfeatureTooltip'. - */ - public void setShowNPfeatureTooltip(final boolean showNPfeatureTooltip) - { - this._showNPfeatureTooltip = showNPfeatureTooltip; - this._has_showNPfeatureTooltip = true; - } - - /** - * Sets the value of field 'showSequenceFeatures'. - * - * @param showSequenceFeatures - * the value of field 'showSequenceFeatures'. - */ - public void setShowSequenceFeatures(final boolean showSequenceFeatures) - { - this._showSequenceFeatures = showSequenceFeatures; - this._has_showSequenceFeatures = true; - } - - /** - * Sets the value of field 'showSequenceLogo'. - * - * @param showSequenceLogo - * the value of field 'showSequenceLogo' - */ - public void setShowSequenceLogo(final boolean showSequenceLogo) - { - this._showSequenceLogo = showSequenceLogo; - this._has_showSequenceLogo = true; - } - - /** - * Sets the value of field 'showText'. - * - * @param showText - * the value of field 'showText'. - */ - public void setShowText(final boolean showText) - { - this._showText = showText; - this._has_showText = true; - } - - /** - * Sets the value of field 'showUnconserved'. - * - * @param showUnconserved - * the value of field 'showUnconserved'. - */ - public void setShowUnconserved(final boolean showUnconserved) - { - this._showUnconserved = showUnconserved; - this._has_showUnconserved = true; - } - - /** - * Sets the value of field 'startRes'. - * - * @param startRes - * the value of field 'startRes'. - */ - public void setStartRes(final int startRes) - { - this._startRes = startRes; - this._has_startRes = true; - } - - /** - * Sets the value of field 'startSeq'. - * - * @param startSeq - * the value of field 'startSeq'. - */ - public void setStartSeq(final int startSeq) - { - this._startSeq = startSeq; - this._has_startSeq = true; - } - - /** - * Sets the value of field 'textCol1'. - * - * @param textCol1 - * the value of field 'textCol1'. - */ - public void setTextCol1(final int textCol1) - { - this._textCol1 = textCol1; - this._has_textCol1 = true; - } - - /** - * Sets the value of field 'textCol2'. - * - * @param textCol2 - * the value of field 'textCol2'. - */ - public void setTextCol2(final int textCol2) - { - this._textCol2 = textCol2; - this._has_textCol2 = true; - } - - /** - * Sets the value of field 'textColThreshold'. - * - * @param textColThreshold - * the value of field 'textColThreshold' - */ - public void setTextColThreshold(final int textColThreshold) - { - this._textColThreshold = textColThreshold; - this._has_textColThreshold = true; - } - - /** - * Sets the value of field 'title'. - * - * @param title - * the value of field 'title'. - */ - public void setTitle(final java.lang.String title) - { - this._title = title; - } - - /** - * Sets the value of field 'viewName'. - * - * @param viewName - * the value of field 'viewName'. - */ - public void setViewName(final java.lang.String viewName) - { - this._viewName = viewName; - } - - /** - * Sets the value of field 'width'. - * - * @param width - * the value of field 'width'. - */ - public void setWidth(final int width) - { - this._width = width; - this._has_width = true; - } - - /** - * Sets the value of field 'wrapAlignment'. - * - * @param wrapAlignment - * the value of field 'wrapAlignment'. - */ - public void setWrapAlignment(final boolean wrapAlignment) - { - this._wrapAlignment = wrapAlignment; - this._has_wrapAlignment = true; - } - - /** - * Sets the value of field 'xpos'. - * - * @param xpos - * the value of field 'xpos'. - */ - public void setXpos(final int xpos) - { - this._xpos = xpos; - this._has_xpos = true; - } - - /** - * Sets the value of field 'ypos'. - * - * @param ypos - * the value of field 'ypos'. - */ - public void setYpos(final int ypos) - { - this._ypos = ypos; - this._has_ypos = true; - } - - /** - * Method unmarshal. - * - * @param reader - * @throws org.exolab.castor.xml.MarshalException - * if object is null or if any SAXException is thrown during - * marshaling - * @throws org.exolab.castor.xml.ValidationException - * if this object is an invalid instance according to the schema - * @return the unmarshaled jalview.schemabinding.version2.Viewport - */ - public static jalview.schemabinding.version2.Viewport unmarshal( - final java.io.Reader reader) - throws org.exolab.castor.xml.MarshalException, - org.exolab.castor.xml.ValidationException - { - return (jalview.schemabinding.version2.Viewport) Unmarshaller - .unmarshal(jalview.schemabinding.version2.Viewport.class, - reader); - } - - /** - * - * - * @throws org.exolab.castor.xml.ValidationException - * if this object is an invalid instance according to the schema - */ - public void validate() throws org.exolab.castor.xml.ValidationException - { - org.exolab.castor.xml.Validator validator = new org.exolab.castor.xml.Validator(); - validator.validate(this); - } + private jalview.schemabinding.version2.AnnotationColours _annotationColours; + + /** + * Field _hiddenColumnsList. + */ + private java.util.Vector _hiddenColumnsList; + + /** + * Field _calcIdParamList. + */ + private java.util.Vector _calcIdParamList; + + + //----------------/ + //- Constructors -/ + //----------------/ + + public Viewport() { + super(); + this._hiddenColumnsList = new java.util.Vector(); + this._calcIdParamList = new java.util.Vector(); + } + + + //-----------/ + //- Methods -/ + //-----------/ + + /** + * + * + * @param vCalcIdParam + * @throws java.lang.IndexOutOfBoundsException if the index + * given is outside the bounds of the collection + */ + public void addCalcIdParam( + final jalview.schemabinding.version2.CalcIdParam vCalcIdParam) + throws java.lang.IndexOutOfBoundsException { + this._calcIdParamList.addElement(vCalcIdParam); + } + + /** + * + * + * @param index + * @param vCalcIdParam + * @throws java.lang.IndexOutOfBoundsException if the index + * given is outside the bounds of the collection + */ + public void addCalcIdParam( + final int index, + final jalview.schemabinding.version2.CalcIdParam vCalcIdParam) + throws java.lang.IndexOutOfBoundsException { + this._calcIdParamList.add(index, vCalcIdParam); + } + + /** + * + * + * @param vHiddenColumns + * @throws java.lang.IndexOutOfBoundsException if the index + * given is outside the bounds of the collection + */ + public void addHiddenColumns( + final jalview.schemabinding.version2.HiddenColumns vHiddenColumns) + throws java.lang.IndexOutOfBoundsException { + this._hiddenColumnsList.addElement(vHiddenColumns); + } + + /** + * + * + * @param index + * @param vHiddenColumns + * @throws java.lang.IndexOutOfBoundsException if the index + * given is outside the bounds of the collection + */ + public void addHiddenColumns( + final int index, + final jalview.schemabinding.version2.HiddenColumns vHiddenColumns) + throws java.lang.IndexOutOfBoundsException { + this._hiddenColumnsList.add(index, vHiddenColumns); + } + + /** + */ + public void deleteCentreColumnLabels( + ) { + this._has_centreColumnLabels= false; + } + + /** + */ + public void deleteConsThreshold( + ) { + this._has_consThreshold= false; + } + + /** + */ + public void deleteConservationSelected( + ) { + this._has_conservationSelected= false; + } + + /** + */ + public void deleteFollowHighlight( + ) { + this._has_followHighlight= false; + } + + /** + */ + public void deleteFollowSelection( + ) { + this._has_followSelection= false; + } + + /** + */ + public void deleteFontSize( + ) { + this._has_fontSize= false; + } + + /** + */ + public void deleteFontStyle( + ) { + this._has_fontStyle= false; + } + + /** + */ + public void deleteGatheredViews( + ) { + this._has_gatheredViews= false; + } + + /** + */ + public void deleteHeight( + ) { + this._has_height= false; + } + + /** + */ + public void deleteIgnoreGapsinConsensus( + ) { + this._has_ignoreGapsinConsensus= false; + } + + /** + */ + public void deleteNormaliseSequenceLogo( + ) { + this._has_normaliseSequenceLogo= false; + } + + /** + */ + public void deletePidSelected( + ) { + this._has_pidSelected= false; + } + + /** + */ + public void deletePidThreshold( + ) { + this._has_pidThreshold= false; + } + + /** + */ + public void deleteRenderGaps( + ) { + this._has_renderGaps= false; + } + + /** + */ + public void deleteRightAlignIds( + ) { + this._has_rightAlignIds= false; + } + + /** + */ + public void deleteShowAnnotation( + ) { + this._has_showAnnotation= false; + } + + /** + */ + public void deleteShowBoxes( + ) { + this._has_showBoxes= false; + } + + /** + */ + public void deleteShowColourText( + ) { + this._has_showColourText= false; + } + + /** + */ + public void deleteShowConsensusHistogram( + ) { + this._has_showConsensusHistogram= false; + } + + /** + */ + public void deleteShowDbRefTooltip( + ) { + this._has_showDbRefTooltip= false; + } + + /** + */ + public void deleteShowFullId( + ) { + this._has_showFullId= false; + } + + /** + */ + public void deleteShowGroupConsensus( + ) { + this._has_showGroupConsensus= false; + } + + /** + */ + public void deleteShowGroupConservation( + ) { + this._has_showGroupConservation= false; + } + + /** + */ + public void deleteShowNPfeatureTooltip( + ) { + this._has_showNPfeatureTooltip= false; + } + + /** + */ + public void deleteShowSequenceFeatures( + ) { + this._has_showSequenceFeatures= false; + } + + /** + */ + public void deleteShowSequenceLogo( + ) { + this._has_showSequenceLogo= false; + } + + /** + */ + public void deleteShowText( + ) { + this._has_showText= false; + } + + /** + */ + public void deleteShowUnconserved( + ) { + this._has_showUnconserved= false; + } + + /** + */ + public void deleteStartRes( + ) { + this._has_startRes= false; + } + + /** + */ + public void deleteStartSeq( + ) { + this._has_startSeq= false; + } + + /** + */ + public void deleteTextCol1( + ) { + this._has_textCol1= false; + } + + /** + */ + public void deleteTextCol2( + ) { + this._has_textCol2= false; + } + + /** + */ + public void deleteTextColThreshold( + ) { + this._has_textColThreshold= false; + } + + /** + */ + public void deleteWidth( + ) { + this._has_width= false; + } + + /** + */ + public void deleteWrapAlignment( + ) { + this._has_wrapAlignment= false; + } + + /** + */ + public void deleteXpos( + ) { + this._has_xpos= false; + } + + /** + */ + public void deleteYpos( + ) { + this._has_ypos= false; + } + + /** + * Method enumerateCalcIdParam. + * + * @return an Enumeration over all + * jalview.schemabinding.version2.CalcIdParam elements + */ + public java.util.Enumeration enumerateCalcIdParam( + ) { + return this._calcIdParamList.elements(); + } + + /** + * Method enumerateHiddenColumns. + * + * @return an Enumeration over all + * jalview.schemabinding.version2.HiddenColumns elements + */ + public java.util.Enumeration enumerateHiddenColumns( + ) { + return this._hiddenColumnsList.elements(); + } + + /** + * Returns the value of field 'annotationColours'. + * + * @return the value of field 'AnnotationColours'. + */ + public jalview.schemabinding.version2.AnnotationColours getAnnotationColours( + ) { + return this._annotationColours; + } + + /** + * Returns the value of field 'bgColour'. + * + * @return the value of field 'BgColour'. + */ + public java.lang.String getBgColour( + ) { + return this._bgColour; + } + + /** + * Method getCalcIdParam. + * + * @param index + * @throws java.lang.IndexOutOfBoundsException if the index + * given is outside the bounds of the collection + * @return the value of the + * jalview.schemabinding.version2.CalcIdParam at the given index + */ + public jalview.schemabinding.version2.CalcIdParam getCalcIdParam( + final int index) + throws java.lang.IndexOutOfBoundsException { + // check bounds for index + if (index < 0 || index >= this._calcIdParamList.size()) { + throw new IndexOutOfBoundsException("getCalcIdParam: Index value '" + index + "' not in range [0.." + (this._calcIdParamList.size() - 1) + "]"); + } + + return (jalview.schemabinding.version2.CalcIdParam) _calcIdParamList.get(index); + } + + /** + * Method getCalcIdParam.Returns the contents of the collection + * in an Array.

Note: Just in case the collection contents + * are changing in another thread, we pass a 0-length Array of + * the correct type into the API call. This way we know + * that the Array returned is of exactly the correct length. + * + * @return this collection as an Array + */ + public jalview.schemabinding.version2.CalcIdParam[] getCalcIdParam( + ) { + jalview.schemabinding.version2.CalcIdParam[] array = new jalview.schemabinding.version2.CalcIdParam[0]; + return (jalview.schemabinding.version2.CalcIdParam[]) this._calcIdParamList.toArray(array); + } + + /** + * Method getCalcIdParamCount. + * + * @return the size of this collection + */ + public int getCalcIdParamCount( + ) { + return this._calcIdParamList.size(); + } + + /** + * Returns the value of field 'centreColumnLabels'. + * + * @return the value of field 'CentreColumnLabels'. + */ + public boolean getCentreColumnLabels( + ) { + return this._centreColumnLabels; + } + + /** + * Returns the value of field 'complementId'. The field + * 'complementId' has the following description: The viewport + * id of this viewport's (cdna/protein) coding complement, if + * any + * + * + * @return the value of field 'ComplementId'. + */ + public java.lang.String getComplementId( + ) { + return this._complementId; + } + + /** + * Returns the value of field 'consThreshold'. + * + * @return the value of field 'ConsThreshold'. + */ + public int getConsThreshold( + ) { + return this._consThreshold; + } + + /** + * Returns the value of field 'conservationSelected'. + * + * @return the value of field 'ConservationSelected'. + */ + public boolean getConservationSelected( + ) { + return this._conservationSelected; + } + + /** + * Returns the value of field 'followHighlight'. + * + * @return the value of field 'FollowHighlight'. + */ + public boolean getFollowHighlight( + ) { + return this._followHighlight; + } + + /** + * Returns the value of field 'followSelection'. + * + * @return the value of field 'FollowSelection'. + */ + public boolean getFollowSelection( + ) { + return this._followSelection; + } + + /** + * Returns the value of field 'fontName'. + * + * @return the value of field 'FontName'. + */ + public java.lang.String getFontName( + ) { + return this._fontName; + } + + /** + * Returns the value of field 'fontSize'. + * + * @return the value of field 'FontSize'. + */ + public int getFontSize( + ) { + return this._fontSize; + } + + /** + * Returns the value of field 'fontStyle'. + * + * @return the value of field 'FontStyle'. + */ + public int getFontStyle( + ) { + return this._fontStyle; + } + + /** + * Returns the value of field 'gatheredViews'. + * + * @return the value of field 'GatheredViews'. + */ + public boolean getGatheredViews( + ) { + return this._gatheredViews; + } + + /** + * Returns the value of field 'height'. + * + * @return the value of field 'Height'. + */ + public int getHeight( + ) { + return this._height; + } + + /** + * Method getHiddenColumns. + * + * @param index + * @throws java.lang.IndexOutOfBoundsException if the index + * given is outside the bounds of the collection + * @return the value of the + * jalview.schemabinding.version2.HiddenColumns at the given + * index + */ + public jalview.schemabinding.version2.HiddenColumns getHiddenColumns( + final int index) + throws java.lang.IndexOutOfBoundsException { + // check bounds for index + if (index < 0 || index >= this._hiddenColumnsList.size()) { + throw new IndexOutOfBoundsException("getHiddenColumns: Index value '" + index + "' not in range [0.." + (this._hiddenColumnsList.size() - 1) + "]"); + } + + return (jalview.schemabinding.version2.HiddenColumns) _hiddenColumnsList.get(index); + } + + /** + * Method getHiddenColumns.Returns the contents of the + * collection in an Array.

Note: Just in case the + * collection contents are changing in another thread, we pass + * a 0-length Array of the correct type into the API call. + * This way we know that the Array returned is of + * exactly the correct length. + * + * @return this collection as an Array + */ + public jalview.schemabinding.version2.HiddenColumns[] getHiddenColumns( + ) { + jalview.schemabinding.version2.HiddenColumns[] array = new jalview.schemabinding.version2.HiddenColumns[0]; + return (jalview.schemabinding.version2.HiddenColumns[]) this._hiddenColumnsList.toArray(array); + } + + /** + * Method getHiddenColumnsCount. + * + * @return the size of this collection + */ + public int getHiddenColumnsCount( + ) { + return this._hiddenColumnsList.size(); + } + + /** + * Returns the value of field 'id'. The field 'id' has the + * following description: unique id used by jalview to + * synchronize between stored and + * instantiated views + * + * + * @return the value of field 'Id'. + */ + public java.lang.String getId( + ) { + return this._id; + } + + /** + * Returns the value of field 'ignoreGapsinConsensus'. + * + * @return the value of field 'IgnoreGapsinConsensus'. + */ + public boolean getIgnoreGapsinConsensus( + ) { + return this._ignoreGapsinConsensus; + } + + /** + * Returns the value of field 'normaliseSequenceLogo'. + * + * @return the value of field 'NormaliseSequenceLogo'. + */ + public boolean getNormaliseSequenceLogo( + ) { + return this._normaliseSequenceLogo; + } + + /** + * Returns the value of field 'pidSelected'. + * + * @return the value of field 'PidSelected'. + */ + public boolean getPidSelected( + ) { + return this._pidSelected; + } + + /** + * Returns the value of field 'pidThreshold'. + * + * @return the value of field 'PidThreshold'. + */ + public int getPidThreshold( + ) { + return this._pidThreshold; + } + + /** + * Returns the value of field 'renderGaps'. + * + * @return the value of field 'RenderGaps'. + */ + public boolean getRenderGaps( + ) { + return this._renderGaps; + } + + /** + * Returns the value of field 'rightAlignIds'. + * + * @return the value of field 'RightAlignIds'. + */ + public boolean getRightAlignIds( + ) { + return this._rightAlignIds; + } + + /** + * Returns the value of field 'sequenceSetId'. + * + * @return the value of field 'SequenceSetId'. + */ + public java.lang.String getSequenceSetId( + ) { + return this._sequenceSetId; + } + + /** + * Returns the value of field 'showAnnotation'. + * + * @return the value of field 'ShowAnnotation'. + */ + public boolean getShowAnnotation( + ) { + return this._showAnnotation; + } + + /** + * Returns the value of field 'showBoxes'. + * + * @return the value of field 'ShowBoxes'. + */ + public boolean getShowBoxes( + ) { + return this._showBoxes; + } + + /** + * Returns the value of field 'showColourText'. + * + * @return the value of field 'ShowColourText'. + */ + public boolean getShowColourText( + ) { + return this._showColourText; + } + + /** + * Returns the value of field 'showConsensusHistogram'. + * + * @return the value of field 'ShowConsensusHistogram'. + */ + public boolean getShowConsensusHistogram( + ) { + return this._showConsensusHistogram; + } + + /** + * Returns the value of field 'showDbRefTooltip'. + * + * @return the value of field 'ShowDbRefTooltip'. + */ + public boolean getShowDbRefTooltip( + ) { + return this._showDbRefTooltip; + } + + /** + * Returns the value of field 'showFullId'. + * + * @return the value of field 'ShowFullId'. + */ + public boolean getShowFullId( + ) { + return this._showFullId; + } + + /** + * Returns the value of field 'showGroupConsensus'. + * + * @return the value of field 'ShowGroupConsensus'. + */ + public boolean getShowGroupConsensus( + ) { + return this._showGroupConsensus; + } + + /** + * Returns the value of field 'showGroupConservation'. + * + * @return the value of field 'ShowGroupConservation'. + */ + public boolean getShowGroupConservation( + ) { + return this._showGroupConservation; + } + + /** + * Returns the value of field 'showNPfeatureTooltip'. + * + * @return the value of field 'ShowNPfeatureTooltip'. + */ + public boolean getShowNPfeatureTooltip( + ) { + return this._showNPfeatureTooltip; + } + + /** + * Returns the value of field 'showSequenceFeatures'. + * + * @return the value of field 'ShowSequenceFeatures'. + */ + public boolean getShowSequenceFeatures( + ) { + return this._showSequenceFeatures; + } + + /** + * Returns the value of field 'showSequenceLogo'. + * + * @return the value of field 'ShowSequenceLogo'. + */ + public boolean getShowSequenceLogo( + ) { + return this._showSequenceLogo; + } + + /** + * Returns the value of field 'showText'. + * + * @return the value of field 'ShowText'. + */ + public boolean getShowText( + ) { + return this._showText; + } + + /** + * Returns the value of field 'showUnconserved'. + * + * @return the value of field 'ShowUnconserved'. + */ + public boolean getShowUnconserved( + ) { + return this._showUnconserved; + } + + /** + * Returns the value of field 'startRes'. + * + * @return the value of field 'StartRes'. + */ + public int getStartRes( + ) { + return this._startRes; + } + + /** + * Returns the value of field 'startSeq'. + * + * @return the value of field 'StartSeq'. + */ + public int getStartSeq( + ) { + return this._startSeq; + } + + /** + * Returns the value of field 'textCol1'. + * + * @return the value of field 'TextCol1'. + */ + public int getTextCol1( + ) { + return this._textCol1; + } + + /** + * Returns the value of field 'textCol2'. + * + * @return the value of field 'TextCol2'. + */ + public int getTextCol2( + ) { + return this._textCol2; + } + + /** + * Returns the value of field 'textColThreshold'. + * + * @return the value of field 'TextColThreshold'. + */ + public int getTextColThreshold( + ) { + return this._textColThreshold; + } + + /** + * Returns the value of field 'title'. + * + * @return the value of field 'Title'. + */ + public java.lang.String getTitle( + ) { + return this._title; + } + + /** + * Returns the value of field 'viewName'. + * + * @return the value of field 'ViewName'. + */ + public java.lang.String getViewName( + ) { + return this._viewName; + } + + /** + * Returns the value of field 'width'. + * + * @return the value of field 'Width'. + */ + public int getWidth( + ) { + return this._width; + } + + /** + * Returns the value of field 'wrapAlignment'. + * + * @return the value of field 'WrapAlignment'. + */ + public boolean getWrapAlignment( + ) { + return this._wrapAlignment; + } + + /** + * Returns the value of field 'xpos'. + * + * @return the value of field 'Xpos'. + */ + public int getXpos( + ) { + return this._xpos; + } + + /** + * Returns the value of field 'ypos'. + * + * @return the value of field 'Ypos'. + */ + public int getYpos( + ) { + return this._ypos; + } + + /** + * Method hasCentreColumnLabels. + * + * @return true if at least one CentreColumnLabels has been adde + */ + public boolean hasCentreColumnLabels( + ) { + return this._has_centreColumnLabels; + } + + /** + * Method hasConsThreshold. + * + * @return true if at least one ConsThreshold has been added + */ + public boolean hasConsThreshold( + ) { + return this._has_consThreshold; + } + + /** + * Method hasConservationSelected. + * + * @return true if at least one ConservationSelected has been + * added + */ + public boolean hasConservationSelected( + ) { + return this._has_conservationSelected; + } + + /** + * Method hasFollowHighlight. + * + * @return true if at least one FollowHighlight has been added + */ + public boolean hasFollowHighlight( + ) { + return this._has_followHighlight; + } + + /** + * Method hasFollowSelection. + * + * @return true if at least one FollowSelection has been added + */ + public boolean hasFollowSelection( + ) { + return this._has_followSelection; + } + + /** + * Method hasFontSize. + * + * @return true if at least one FontSize has been added + */ + public boolean hasFontSize( + ) { + return this._has_fontSize; + } + + /** + * Method hasFontStyle. + * + * @return true if at least one FontStyle has been added + */ + public boolean hasFontStyle( + ) { + return this._has_fontStyle; + } + + /** + * Method hasGatheredViews. + * + * @return true if at least one GatheredViews has been added + */ + public boolean hasGatheredViews( + ) { + return this._has_gatheredViews; + } + + /** + * Method hasHeight. + * + * @return true if at least one Height has been added + */ + public boolean hasHeight( + ) { + return this._has_height; + } + + /** + * Method hasIgnoreGapsinConsensus. + * + * @return true if at least one IgnoreGapsinConsensus has been + * added + */ + public boolean hasIgnoreGapsinConsensus( + ) { + return this._has_ignoreGapsinConsensus; + } + + /** + * Method hasNormaliseSequenceLogo. + * + * @return true if at least one NormaliseSequenceLogo has been + * added + */ + public boolean hasNormaliseSequenceLogo( + ) { + return this._has_normaliseSequenceLogo; + } + + /** + * Method hasPidSelected. + * + * @return true if at least one PidSelected has been added + */ + public boolean hasPidSelected( + ) { + return this._has_pidSelected; + } + + /** + * Method hasPidThreshold. + * + * @return true if at least one PidThreshold has been added + */ + public boolean hasPidThreshold( + ) { + return this._has_pidThreshold; + } + + /** + * Method hasRenderGaps. + * + * @return true if at least one RenderGaps has been added + */ + public boolean hasRenderGaps( + ) { + return this._has_renderGaps; + } + + /** + * Method hasRightAlignIds. + * + * @return true if at least one RightAlignIds has been added + */ + public boolean hasRightAlignIds( + ) { + return this._has_rightAlignIds; + } + + /** + * Method hasShowAnnotation. + * + * @return true if at least one ShowAnnotation has been added + */ + public boolean hasShowAnnotation( + ) { + return this._has_showAnnotation; + } + + /** + * Method hasShowBoxes. + * + * @return true if at least one ShowBoxes has been added + */ + public boolean hasShowBoxes( + ) { + return this._has_showBoxes; + } + + /** + * Method hasShowColourText. + * + * @return true if at least one ShowColourText has been added + */ + public boolean hasShowColourText( + ) { + return this._has_showColourText; + } + + /** + * Method hasShowConsensusHistogram. + * + * @return true if at least one ShowConsensusHistogram has been + * added + */ + public boolean hasShowConsensusHistogram( + ) { + return this._has_showConsensusHistogram; + } + + /** + * Method hasShowDbRefTooltip. + * + * @return true if at least one ShowDbRefTooltip has been added + */ + public boolean hasShowDbRefTooltip( + ) { + return this._has_showDbRefTooltip; + } + + /** + * Method hasShowFullId. + * + * @return true if at least one ShowFullId has been added + */ + public boolean hasShowFullId( + ) { + return this._has_showFullId; + } + + /** + * Method hasShowGroupConsensus. + * + * @return true if at least one ShowGroupConsensus has been adde + */ + public boolean hasShowGroupConsensus( + ) { + return this._has_showGroupConsensus; + } + + /** + * Method hasShowGroupConservation. + * + * @return true if at least one ShowGroupConservation has been + * added + */ + public boolean hasShowGroupConservation( + ) { + return this._has_showGroupConservation; + } + + /** + * Method hasShowNPfeatureTooltip. + * + * @return true if at least one ShowNPfeatureTooltip has been + * added + */ + public boolean hasShowNPfeatureTooltip( + ) { + return this._has_showNPfeatureTooltip; + } + + /** + * Method hasShowSequenceFeatures. + * + * @return true if at least one ShowSequenceFeatures has been + * added + */ + public boolean hasShowSequenceFeatures( + ) { + return this._has_showSequenceFeatures; + } + + /** + * Method hasShowSequenceLogo. + * + * @return true if at least one ShowSequenceLogo has been added + */ + public boolean hasShowSequenceLogo( + ) { + return this._has_showSequenceLogo; + } + + /** + * Method hasShowText. + * + * @return true if at least one ShowText has been added + */ + public boolean hasShowText( + ) { + return this._has_showText; + } + + /** + * Method hasShowUnconserved. + * + * @return true if at least one ShowUnconserved has been added + */ + public boolean hasShowUnconserved( + ) { + return this._has_showUnconserved; + } + + /** + * Method hasStartRes. + * + * @return true if at least one StartRes has been added + */ + public boolean hasStartRes( + ) { + return this._has_startRes; + } + + /** + * Method hasStartSeq. + * + * @return true if at least one StartSeq has been added + */ + public boolean hasStartSeq( + ) { + return this._has_startSeq; + } + + /** + * Method hasTextCol1. + * + * @return true if at least one TextCol1 has been added + */ + public boolean hasTextCol1( + ) { + return this._has_textCol1; + } + + /** + * Method hasTextCol2. + * + * @return true if at least one TextCol2 has been added + */ + public boolean hasTextCol2( + ) { + return this._has_textCol2; + } + + /** + * Method hasTextColThreshold. + * + * @return true if at least one TextColThreshold has been added + */ + public boolean hasTextColThreshold( + ) { + return this._has_textColThreshold; + } + + /** + * Method hasWidth. + * + * @return true if at least one Width has been added + */ + public boolean hasWidth( + ) { + return this._has_width; + } + + /** + * Method hasWrapAlignment. + * + * @return true if at least one WrapAlignment has been added + */ + public boolean hasWrapAlignment( + ) { + return this._has_wrapAlignment; + } + + /** + * Method hasXpos. + * + * @return true if at least one Xpos has been added + */ + public boolean hasXpos( + ) { + return this._has_xpos; + } + + /** + * Method hasYpos. + * + * @return true if at least one Ypos has been added + */ + public boolean hasYpos( + ) { + return this._has_ypos; + } + + /** + * Returns the value of field 'centreColumnLabels'. + * + * @return the value of field 'CentreColumnLabels'. + */ + public boolean isCentreColumnLabels( + ) { + return this._centreColumnLabels; + } + + /** + * Returns the value of field 'conservationSelected'. + * + * @return the value of field 'ConservationSelected'. + */ + public boolean isConservationSelected( + ) { + return this._conservationSelected; + } + + /** + * Returns the value of field 'followHighlight'. + * + * @return the value of field 'FollowHighlight'. + */ + public boolean isFollowHighlight( + ) { + return this._followHighlight; + } + + /** + * Returns the value of field 'followSelection'. + * + * @return the value of field 'FollowSelection'. + */ + public boolean isFollowSelection( + ) { + return this._followSelection; + } + + /** + * Returns the value of field 'gatheredViews'. + * + * @return the value of field 'GatheredViews'. + */ + public boolean isGatheredViews( + ) { + return this._gatheredViews; + } + + /** + * Returns the value of field 'ignoreGapsinConsensus'. + * + * @return the value of field 'IgnoreGapsinConsensus'. + */ + public boolean isIgnoreGapsinConsensus( + ) { + return this._ignoreGapsinConsensus; + } + + /** + * Returns the value of field 'normaliseSequenceLogo'. + * + * @return the value of field 'NormaliseSequenceLogo'. + */ + public boolean isNormaliseSequenceLogo( + ) { + return this._normaliseSequenceLogo; + } + + /** + * Returns the value of field 'pidSelected'. + * + * @return the value of field 'PidSelected'. + */ + public boolean isPidSelected( + ) { + return this._pidSelected; + } + + /** + * Returns the value of field 'renderGaps'. + * + * @return the value of field 'RenderGaps'. + */ + public boolean isRenderGaps( + ) { + return this._renderGaps; + } + + /** + * Returns the value of field 'rightAlignIds'. + * + * @return the value of field 'RightAlignIds'. + */ + public boolean isRightAlignIds( + ) { + return this._rightAlignIds; + } + + /** + * Returns the value of field 'showAnnotation'. + * + * @return the value of field 'ShowAnnotation'. + */ + public boolean isShowAnnotation( + ) { + return this._showAnnotation; + } + + /** + * Returns the value of field 'showBoxes'. + * + * @return the value of field 'ShowBoxes'. + */ + public boolean isShowBoxes( + ) { + return this._showBoxes; + } + + /** + * Returns the value of field 'showColourText'. + * + * @return the value of field 'ShowColourText'. + */ + public boolean isShowColourText( + ) { + return this._showColourText; + } + + /** + * Returns the value of field 'showConsensusHistogram'. + * + * @return the value of field 'ShowConsensusHistogram'. + */ + public boolean isShowConsensusHistogram( + ) { + return this._showConsensusHistogram; + } + + /** + * Returns the value of field 'showDbRefTooltip'. + * + * @return the value of field 'ShowDbRefTooltip'. + */ + public boolean isShowDbRefTooltip( + ) { + return this._showDbRefTooltip; + } + + /** + * Returns the value of field 'showFullId'. + * + * @return the value of field 'ShowFullId'. + */ + public boolean isShowFullId( + ) { + return this._showFullId; + } + + /** + * Returns the value of field 'showGroupConsensus'. + * + * @return the value of field 'ShowGroupConsensus'. + */ + public boolean isShowGroupConsensus( + ) { + return this._showGroupConsensus; + } + + /** + * Returns the value of field 'showGroupConservation'. + * + * @return the value of field 'ShowGroupConservation'. + */ + public boolean isShowGroupConservation( + ) { + return this._showGroupConservation; + } + + /** + * Returns the value of field 'showNPfeatureTooltip'. + * + * @return the value of field 'ShowNPfeatureTooltip'. + */ + public boolean isShowNPfeatureTooltip( + ) { + return this._showNPfeatureTooltip; + } + + /** + * Returns the value of field 'showSequenceFeatures'. + * + * @return the value of field 'ShowSequenceFeatures'. + */ + public boolean isShowSequenceFeatures( + ) { + return this._showSequenceFeatures; + } + + /** + * Returns the value of field 'showSequenceLogo'. + * + * @return the value of field 'ShowSequenceLogo'. + */ + public boolean isShowSequenceLogo( + ) { + return this._showSequenceLogo; + } + + /** + * Returns the value of field 'showText'. + * + * @return the value of field 'ShowText'. + */ + public boolean isShowText( + ) { + return this._showText; + } + + /** + * Returns the value of field 'showUnconserved'. + * + * @return the value of field 'ShowUnconserved'. + */ + public boolean isShowUnconserved( + ) { + return this._showUnconserved; + } + + /** + * Method isValid. + * + * @return true if this object is valid according to the schema + */ + public boolean isValid( + ) { + try { + validate(); + } catch (org.exolab.castor.xml.ValidationException vex) { + return false; + } + return true; + } + + /** + * Returns the value of field 'wrapAlignment'. + * + * @return the value of field 'WrapAlignment'. + */ + public boolean isWrapAlignment( + ) { + return this._wrapAlignment; + } + + /** + * + * + * @param out + * @throws org.exolab.castor.xml.MarshalException if object is + * null or if any SAXException is thrown during marshaling + * @throws org.exolab.castor.xml.ValidationException if this + * object is an invalid instance according to the schema + */ + public void marshal( + final java.io.Writer out) + throws org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + Marshaller.marshal(this, out); + } + + /** + * + * + * @param handler + * @throws java.io.IOException if an IOException occurs during + * marshaling + * @throws org.exolab.castor.xml.ValidationException if this + * object is an invalid instance according to the schema + * @throws org.exolab.castor.xml.MarshalException if object is + * null or if any SAXException is thrown during marshaling + */ + public void marshal( + final org.xml.sax.ContentHandler handler) + throws java.io.IOException, org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + Marshaller.marshal(this, handler); + } + + /** + */ + public void removeAllCalcIdParam( + ) { + this._calcIdParamList.clear(); + } + + /** + */ + public void removeAllHiddenColumns( + ) { + this._hiddenColumnsList.clear(); + } + + /** + * Method removeCalcIdParam. + * + * @param vCalcIdParam + * @return true if the object was removed from the collection. + */ + public boolean removeCalcIdParam( + final jalview.schemabinding.version2.CalcIdParam vCalcIdParam) { + boolean removed = _calcIdParamList.remove(vCalcIdParam); + return removed; + } + + /** + * Method removeCalcIdParamAt. + * + * @param index + * @return the element removed from the collection + */ + public jalview.schemabinding.version2.CalcIdParam removeCalcIdParamAt( + final int index) { + java.lang.Object obj = this._calcIdParamList.remove(index); + return (jalview.schemabinding.version2.CalcIdParam) obj; + } + + /** + * Method removeHiddenColumns. + * + * @param vHiddenColumns + * @return true if the object was removed from the collection. + */ + public boolean removeHiddenColumns( + final jalview.schemabinding.version2.HiddenColumns vHiddenColumns) { + boolean removed = _hiddenColumnsList.remove(vHiddenColumns); + return removed; + } + + /** + * Method removeHiddenColumnsAt. + * + * @param index + * @return the element removed from the collection + */ + public jalview.schemabinding.version2.HiddenColumns removeHiddenColumnsAt( + final int index) { + java.lang.Object obj = this._hiddenColumnsList.remove(index); + return (jalview.schemabinding.version2.HiddenColumns) obj; + } + + /** + * Sets the value of field 'annotationColours'. + * + * @param annotationColours the value of field + * 'annotationColours'. + */ + public void setAnnotationColours( + final jalview.schemabinding.version2.AnnotationColours annotationColours) { + this._annotationColours = annotationColours; + } + + /** + * Sets the value of field 'bgColour'. + * + * @param bgColour the value of field 'bgColour'. + */ + public void setBgColour( + final java.lang.String bgColour) { + this._bgColour = bgColour; + } + + /** + * + * + * @param index + * @param vCalcIdParam + * @throws java.lang.IndexOutOfBoundsException if the index + * given is outside the bounds of the collection + */ + public void setCalcIdParam( + final int index, + final jalview.schemabinding.version2.CalcIdParam vCalcIdParam) + throws java.lang.IndexOutOfBoundsException { + // check bounds for index + if (index < 0 || index >= this._calcIdParamList.size()) { + throw new IndexOutOfBoundsException("setCalcIdParam: Index value '" + index + "' not in range [0.." + (this._calcIdParamList.size() - 1) + "]"); + } + + this._calcIdParamList.set(index, vCalcIdParam); + } + + /** + * + * + * @param vCalcIdParamArray + */ + public void setCalcIdParam( + final jalview.schemabinding.version2.CalcIdParam[] vCalcIdParamArray) { + //-- copy array + _calcIdParamList.clear(); + + for (int i = 0; i < vCalcIdParamArray.length; i++) { + this._calcIdParamList.add(vCalcIdParamArray[i]); + } + } + + /** + * Sets the value of field 'centreColumnLabels'. + * + * @param centreColumnLabels the value of field + * 'centreColumnLabels'. + */ + public void setCentreColumnLabels( + final boolean centreColumnLabels) { + this._centreColumnLabels = centreColumnLabels; + this._has_centreColumnLabels = true; + } + + /** + * Sets the value of field 'complementId'. The field + * 'complementId' has the following description: The viewport + * id of this viewport's (cdna/protein) coding complement, if + * any + * + * + * @param complementId the value of field 'complementId'. + */ + public void setComplementId( + final java.lang.String complementId) { + this._complementId = complementId; + } + + /** + * Sets the value of field 'consThreshold'. + * + * @param consThreshold the value of field 'consThreshold'. + */ + public void setConsThreshold( + final int consThreshold) { + this._consThreshold = consThreshold; + this._has_consThreshold = true; + } + + /** + * Sets the value of field 'conservationSelected'. + * + * @param conservationSelected the value of field + * 'conservationSelected'. + */ + public void setConservationSelected( + final boolean conservationSelected) { + this._conservationSelected = conservationSelected; + this._has_conservationSelected = true; + } + + /** + * Sets the value of field 'followHighlight'. + * + * @param followHighlight the value of field 'followHighlight'. + */ + public void setFollowHighlight( + final boolean followHighlight) { + this._followHighlight = followHighlight; + this._has_followHighlight = true; + } + + /** + * Sets the value of field 'followSelection'. + * + * @param followSelection the value of field 'followSelection'. + */ + public void setFollowSelection( + final boolean followSelection) { + this._followSelection = followSelection; + this._has_followSelection = true; + } + + /** + * Sets the value of field 'fontName'. + * + * @param fontName the value of field 'fontName'. + */ + public void setFontName( + final java.lang.String fontName) { + this._fontName = fontName; + } + + /** + * Sets the value of field 'fontSize'. + * + * @param fontSize the value of field 'fontSize'. + */ + public void setFontSize( + final int fontSize) { + this._fontSize = fontSize; + this._has_fontSize = true; + } + + /** + * Sets the value of field 'fontStyle'. + * + * @param fontStyle the value of field 'fontStyle'. + */ + public void setFontStyle( + final int fontStyle) { + this._fontStyle = fontStyle; + this._has_fontStyle = true; + } + + /** + * Sets the value of field 'gatheredViews'. + * + * @param gatheredViews the value of field 'gatheredViews'. + */ + public void setGatheredViews( + final boolean gatheredViews) { + this._gatheredViews = gatheredViews; + this._has_gatheredViews = true; + } + + /** + * Sets the value of field 'height'. + * + * @param height the value of field 'height'. + */ + public void setHeight( + final int height) { + this._height = height; + this._has_height = true; + } + + /** + * + * + * @param index + * @param vHiddenColumns + * @throws java.lang.IndexOutOfBoundsException if the index + * given is outside the bounds of the collection + */ + public void setHiddenColumns( + final int index, + final jalview.schemabinding.version2.HiddenColumns vHiddenColumns) + throws java.lang.IndexOutOfBoundsException { + // check bounds for index + if (index < 0 || index >= this._hiddenColumnsList.size()) { + throw new IndexOutOfBoundsException("setHiddenColumns: Index value '" + index + "' not in range [0.." + (this._hiddenColumnsList.size() - 1) + "]"); + } + + this._hiddenColumnsList.set(index, vHiddenColumns); + } + + /** + * + * + * @param vHiddenColumnsArray + */ + public void setHiddenColumns( + final jalview.schemabinding.version2.HiddenColumns[] vHiddenColumnsArray) { + //-- copy array + _hiddenColumnsList.clear(); + + for (int i = 0; i < vHiddenColumnsArray.length; i++) { + this._hiddenColumnsList.add(vHiddenColumnsArray[i]); + } + } + + /** + * Sets the value of field 'id'. The field 'id' has the + * following description: unique id used by jalview to + * synchronize between stored and + * instantiated views + * + * + * @param id the value of field 'id'. + */ + public void setId( + final java.lang.String id) { + this._id = id; + } + + /** + * Sets the value of field 'ignoreGapsinConsensus'. + * + * @param ignoreGapsinConsensus the value of field + * 'ignoreGapsinConsensus'. + */ + public void setIgnoreGapsinConsensus( + final boolean ignoreGapsinConsensus) { + this._ignoreGapsinConsensus = ignoreGapsinConsensus; + this._has_ignoreGapsinConsensus = true; + } + + /** + * Sets the value of field 'normaliseSequenceLogo'. + * + * @param normaliseSequenceLogo the value of field + * 'normaliseSequenceLogo'. + */ + public void setNormaliseSequenceLogo( + final boolean normaliseSequenceLogo) { + this._normaliseSequenceLogo = normaliseSequenceLogo; + this._has_normaliseSequenceLogo = true; + } + + /** + * Sets the value of field 'pidSelected'. + * + * @param pidSelected the value of field 'pidSelected'. + */ + public void setPidSelected( + final boolean pidSelected) { + this._pidSelected = pidSelected; + this._has_pidSelected = true; + } + + /** + * Sets the value of field 'pidThreshold'. + * + * @param pidThreshold the value of field 'pidThreshold'. + */ + public void setPidThreshold( + final int pidThreshold) { + this._pidThreshold = pidThreshold; + this._has_pidThreshold = true; + } + + /** + * Sets the value of field 'renderGaps'. + * + * @param renderGaps the value of field 'renderGaps'. + */ + public void setRenderGaps( + final boolean renderGaps) { + this._renderGaps = renderGaps; + this._has_renderGaps = true; + } + + /** + * Sets the value of field 'rightAlignIds'. + * + * @param rightAlignIds the value of field 'rightAlignIds'. + */ + public void setRightAlignIds( + final boolean rightAlignIds) { + this._rightAlignIds = rightAlignIds; + this._has_rightAlignIds = true; + } + + /** + * Sets the value of field 'sequenceSetId'. + * + * @param sequenceSetId the value of field 'sequenceSetId'. + */ + public void setSequenceSetId( + final java.lang.String sequenceSetId) { + this._sequenceSetId = sequenceSetId; + } + + /** + * Sets the value of field 'showAnnotation'. + * + * @param showAnnotation the value of field 'showAnnotation'. + */ + public void setShowAnnotation( + final boolean showAnnotation) { + this._showAnnotation = showAnnotation; + this._has_showAnnotation = true; + } + + /** + * Sets the value of field 'showBoxes'. + * + * @param showBoxes the value of field 'showBoxes'. + */ + public void setShowBoxes( + final boolean showBoxes) { + this._showBoxes = showBoxes; + this._has_showBoxes = true; + } + + /** + * Sets the value of field 'showColourText'. + * + * @param showColourText the value of field 'showColourText'. + */ + public void setShowColourText( + final boolean showColourText) { + this._showColourText = showColourText; + this._has_showColourText = true; + } + + /** + * Sets the value of field 'showConsensusHistogram'. + * + * @param showConsensusHistogram the value of field + * 'showConsensusHistogram'. + */ + public void setShowConsensusHistogram( + final boolean showConsensusHistogram) { + this._showConsensusHistogram = showConsensusHistogram; + this._has_showConsensusHistogram = true; + } + + /** + * Sets the value of field 'showDbRefTooltip'. + * + * @param showDbRefTooltip the value of field 'showDbRefTooltip' + */ + public void setShowDbRefTooltip( + final boolean showDbRefTooltip) { + this._showDbRefTooltip = showDbRefTooltip; + this._has_showDbRefTooltip = true; + } + + /** + * Sets the value of field 'showFullId'. + * + * @param showFullId the value of field 'showFullId'. + */ + public void setShowFullId( + final boolean showFullId) { + this._showFullId = showFullId; + this._has_showFullId = true; + } + + /** + * Sets the value of field 'showGroupConsensus'. + * + * @param showGroupConsensus the value of field + * 'showGroupConsensus'. + */ + public void setShowGroupConsensus( + final boolean showGroupConsensus) { + this._showGroupConsensus = showGroupConsensus; + this._has_showGroupConsensus = true; + } + + /** + * Sets the value of field 'showGroupConservation'. + * + * @param showGroupConservation the value of field + * 'showGroupConservation'. + */ + public void setShowGroupConservation( + final boolean showGroupConservation) { + this._showGroupConservation = showGroupConservation; + this._has_showGroupConservation = true; + } + + /** + * Sets the value of field 'showNPfeatureTooltip'. + * + * @param showNPfeatureTooltip the value of field + * 'showNPfeatureTooltip'. + */ + public void setShowNPfeatureTooltip( + final boolean showNPfeatureTooltip) { + this._showNPfeatureTooltip = showNPfeatureTooltip; + this._has_showNPfeatureTooltip = true; + } + + /** + * Sets the value of field 'showSequenceFeatures'. + * + * @param showSequenceFeatures the value of field + * 'showSequenceFeatures'. + */ + public void setShowSequenceFeatures( + final boolean showSequenceFeatures) { + this._showSequenceFeatures = showSequenceFeatures; + this._has_showSequenceFeatures = true; + } + + /** + * Sets the value of field 'showSequenceLogo'. + * + * @param showSequenceLogo the value of field 'showSequenceLogo' + */ + public void setShowSequenceLogo( + final boolean showSequenceLogo) { + this._showSequenceLogo = showSequenceLogo; + this._has_showSequenceLogo = true; + } + + /** + * Sets the value of field 'showText'. + * + * @param showText the value of field 'showText'. + */ + public void setShowText( + final boolean showText) { + this._showText = showText; + this._has_showText = true; + } + + /** + * Sets the value of field 'showUnconserved'. + * + * @param showUnconserved the value of field 'showUnconserved'. + */ + public void setShowUnconserved( + final boolean showUnconserved) { + this._showUnconserved = showUnconserved; + this._has_showUnconserved = true; + } + + /** + * Sets the value of field 'startRes'. + * + * @param startRes the value of field 'startRes'. + */ + public void setStartRes( + final int startRes) { + this._startRes = startRes; + this._has_startRes = true; + } + + /** + * Sets the value of field 'startSeq'. + * + * @param startSeq the value of field 'startSeq'. + */ + public void setStartSeq( + final int startSeq) { + this._startSeq = startSeq; + this._has_startSeq = true; + } + + /** + * Sets the value of field 'textCol1'. + * + * @param textCol1 the value of field 'textCol1'. + */ + public void setTextCol1( + final int textCol1) { + this._textCol1 = textCol1; + this._has_textCol1 = true; + } + + /** + * Sets the value of field 'textCol2'. + * + * @param textCol2 the value of field 'textCol2'. + */ + public void setTextCol2( + final int textCol2) { + this._textCol2 = textCol2; + this._has_textCol2 = true; + } + + /** + * Sets the value of field 'textColThreshold'. + * + * @param textColThreshold the value of field 'textColThreshold' + */ + public void setTextColThreshold( + final int textColThreshold) { + this._textColThreshold = textColThreshold; + this._has_textColThreshold = true; + } + + /** + * Sets the value of field 'title'. + * + * @param title the value of field 'title'. + */ + public void setTitle( + final java.lang.String title) { + this._title = title; + } + + /** + * Sets the value of field 'viewName'. + * + * @param viewName the value of field 'viewName'. + */ + public void setViewName( + final java.lang.String viewName) { + this._viewName = viewName; + } + + /** + * Sets the value of field 'width'. + * + * @param width the value of field 'width'. + */ + public void setWidth( + final int width) { + this._width = width; + this._has_width = true; + } + + /** + * Sets the value of field 'wrapAlignment'. + * + * @param wrapAlignment the value of field 'wrapAlignment'. + */ + public void setWrapAlignment( + final boolean wrapAlignment) { + this._wrapAlignment = wrapAlignment; + this._has_wrapAlignment = true; + } + + /** + * Sets the value of field 'xpos'. + * + * @param xpos the value of field 'xpos'. + */ + public void setXpos( + final int xpos) { + this._xpos = xpos; + this._has_xpos = true; + } + + /** + * Sets the value of field 'ypos'. + * + * @param ypos the value of field 'ypos'. + */ + public void setYpos( + final int ypos) { + this._ypos = ypos; + this._has_ypos = true; + } + + /** + * Method unmarshal. + * + * @param reader + * @throws org.exolab.castor.xml.MarshalException if object is + * null or if any SAXException is thrown during marshaling + * @throws org.exolab.castor.xml.ValidationException if this + * object is an invalid instance according to the schema + * @return the unmarshaled + * jalview.schemabinding.version2.Viewport + */ + public static jalview.schemabinding.version2.Viewport unmarshal( + final java.io.Reader reader) + throws org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException { + return (jalview.schemabinding.version2.Viewport) Unmarshaller.unmarshal(jalview.schemabinding.version2.Viewport.class, reader); + } + + /** + * + * + * @throws org.exolab.castor.xml.ValidationException if this + * object is an invalid instance according to the schema + */ + public void validate( + ) + throws org.exolab.castor.xml.ValidationException { + org.exolab.castor.xml.Validator validator = new org.exolab.castor.xml.Validator(); + validator.validate(this); + } } diff --git a/src/jalview/schemabinding/version2/descriptors/ViewportDescriptor.java b/src/jalview/schemabinding/version2/descriptors/ViewportDescriptor.java index 2204639..81615a1 100644 --- a/src/jalview/schemabinding/version2/descriptors/ViewportDescriptor.java +++ b/src/jalview/schemabinding/version2/descriptors/ViewportDescriptor.java @@ -20,8 +20,8 @@ */ package jalview.schemabinding.version2.descriptors; -//---------------------------------/ -//- Imported classes and packages -/ + //---------------------------------/ + //- Imported classes and packages -/ //---------------------------------/ import jalview.schemabinding.version2.Viewport; @@ -31,2600 +31,2061 @@ import jalview.schemabinding.version2.Viewport; * * @version $Revision$ $Date$ */ -public class ViewportDescriptor extends - org.exolab.castor.xml.util.XMLClassDescriptorImpl -{ - - // --------------------------/ - // - Class/Member Variables -/ - // --------------------------/ - - /** - * Field _elementDefinition. - */ - private boolean _elementDefinition; - - /** - * Field _nsPrefix. - */ - private java.lang.String _nsPrefix; - - /** - * Field _nsURI. - */ - private java.lang.String _nsURI; - - /** - * Field _xmlName. - */ - private java.lang.String _xmlName; - - // ----------------/ - // - Constructors -/ - // ----------------/ - - public ViewportDescriptor() - { - super(); - _nsURI = "www.jalview.org"; - _xmlName = "Viewport"; - _elementDefinition = true; - - // -- set grouping compositor - setCompositorAsSequence(); - org.exolab.castor.xml.util.XMLFieldDescriptorImpl desc = null; - org.exolab.castor.mapping.FieldHandler handler = null; - org.exolab.castor.xml.FieldValidator fieldValidator = null; - // -- initialize attribute descriptors - - // -- _conservationSelected - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_conservationSelected", - "conservationSelected", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasConservationSelected()) - { - return null; - } - return (target.getConservationSelected() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteConservationSelected(); - return; - } - target.setConservationSelected(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _conservationSelected - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); +public class ViewportDescriptor extends org.exolab.castor.xml.util.XMLClassDescriptorImpl { + + + //--------------------------/ + //- Class/Member Variables -/ + //--------------------------/ + + /** + * Field _elementDefinition. + */ + private boolean _elementDefinition; + + /** + * Field _nsPrefix. + */ + private java.lang.String _nsPrefix; + + /** + * Field _nsURI. + */ + private java.lang.String _nsURI; + + /** + * Field _xmlName. + */ + private java.lang.String _xmlName; + + + //----------------/ + //- Constructors -/ + //----------------/ + + public ViewportDescriptor() { + super(); + _nsURI = "www.jalview.org"; + _xmlName = "Viewport"; + _elementDefinition = true; + + //-- set grouping compositor + setCompositorAsSequence(); + org.exolab.castor.xml.util.XMLFieldDescriptorImpl desc = null; + org.exolab.castor.mapping.FieldHandler handler = null; + org.exolab.castor.xml.FieldValidator fieldValidator = null; + //-- initialize attribute descriptors + + //-- _conservationSelected + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_conservationSelected", "conservationSelected", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasConservationSelected()) { return null; } + return (target.getConservationSelected() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteConservationSelected(); + return; + } + target.setConservationSelected( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _conservationSelected + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _pidSelected + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_pidSelected", "pidSelected", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasPidSelected()) { return null; } + return (target.getPidSelected() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deletePidSelected(); + return; + } + target.setPidSelected( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _pidSelected + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _bgColour + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_bgColour", "bgColour", org.exolab.castor.xml.NodeType.Attribute); + desc.setImmutable(true); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getBgColour(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.setBgColour( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _bgColour + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.StringValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.StringValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setWhiteSpace("preserve"); + } + desc.setValidator(fieldValidator); + //-- _consThreshold + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_consThreshold", "consThreshold", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasConsThreshold()) { return null; } + return new java.lang.Integer(target.getConsThreshold()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteConsThreshold(); + return; + } + target.setConsThreshold( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _consThreshold + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _pidThreshold + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_pidThreshold", "pidThreshold", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasPidThreshold()) { return null; } + return new java.lang.Integer(target.getPidThreshold()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deletePidThreshold(); + return; + } + target.setPidThreshold( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _pidThreshold + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _title + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_title", "title", org.exolab.castor.xml.NodeType.Attribute); + desc.setImmutable(true); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getTitle(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.setTitle( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _title + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.StringValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.StringValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setWhiteSpace("preserve"); + } + desc.setValidator(fieldValidator); + //-- _showFullId + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showFullId", "showFullId", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowFullId()) { return null; } + return (target.getShowFullId() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowFullId(); + return; + } + target.setShowFullId( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showFullId + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _rightAlignIds + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_rightAlignIds", "rightAlignIds", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasRightAlignIds()) { return null; } + return (target.getRightAlignIds() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteRightAlignIds(); + return; + } + target.setRightAlignIds( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _rightAlignIds + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showText + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showText", "showText", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowText()) { return null; } + return (target.getShowText() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowText(); + return; + } + target.setShowText( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showText + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showColourText + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showColourText", "showColourText", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowColourText()) { return null; } + return (target.getShowColourText() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowColourText(); + return; + } + target.setShowColourText( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showColourText + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showUnconserved + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showUnconserved", "showUnconserved", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowUnconserved()) { return null; } + return (target.getShowUnconserved() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowUnconserved(); + return; + } + target.setShowUnconserved( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showUnconserved + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showBoxes + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showBoxes", "showBoxes", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowBoxes()) { return null; } + return (target.getShowBoxes() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowBoxes(); + return; + } + target.setShowBoxes( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showBoxes + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _wrapAlignment + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_wrapAlignment", "wrapAlignment", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasWrapAlignment()) { return null; } + return (target.getWrapAlignment() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteWrapAlignment(); + return; + } + target.setWrapAlignment( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _wrapAlignment + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _renderGaps + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_renderGaps", "renderGaps", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasRenderGaps()) { return null; } + return (target.getRenderGaps() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteRenderGaps(); + return; + } + target.setRenderGaps( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _renderGaps + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showSequenceFeatures + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showSequenceFeatures", "showSequenceFeatures", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowSequenceFeatures()) { return null; } + return (target.getShowSequenceFeatures() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowSequenceFeatures(); + return; + } + target.setShowSequenceFeatures( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showSequenceFeatures + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showNPfeatureTooltip + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showNPfeatureTooltip", "showNPfeatureTooltip", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowNPfeatureTooltip()) { return null; } + return (target.getShowNPfeatureTooltip() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowNPfeatureTooltip(); + return; + } + target.setShowNPfeatureTooltip( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showNPfeatureTooltip + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showDbRefTooltip + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showDbRefTooltip", "showDbRefTooltip", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowDbRefTooltip()) { return null; } + return (target.getShowDbRefTooltip() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowDbRefTooltip(); + return; + } + target.setShowDbRefTooltip( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showDbRefTooltip + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _followHighlight + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_followHighlight", "followHighlight", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasFollowHighlight()) { return null; } + return (target.getFollowHighlight() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteFollowHighlight(); + return; + } + target.setFollowHighlight( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _followHighlight + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _followSelection + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_followSelection", "followSelection", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasFollowSelection()) { return null; } + return (target.getFollowSelection() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteFollowSelection(); + return; + } + target.setFollowSelection( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _followSelection + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showAnnotation + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showAnnotation", "showAnnotation", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowAnnotation()) { return null; } + return (target.getShowAnnotation() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowAnnotation(); + return; + } + target.setShowAnnotation( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showAnnotation + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _centreColumnLabels + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_centreColumnLabels", "centreColumnLabels", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasCentreColumnLabels()) { return null; } + return (target.getCentreColumnLabels() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteCentreColumnLabels(); + return; + } + target.setCentreColumnLabels( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _centreColumnLabels + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showGroupConservation + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showGroupConservation", "showGroupConservation", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowGroupConservation()) { return null; } + return (target.getShowGroupConservation() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowGroupConservation(); + return; + } + target.setShowGroupConservation( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showGroupConservation + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showGroupConsensus + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showGroupConsensus", "showGroupConsensus", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowGroupConsensus()) { return null; } + return (target.getShowGroupConsensus() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowGroupConsensus(); + return; + } + target.setShowGroupConsensus( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showGroupConsensus + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showConsensusHistogram + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showConsensusHistogram", "showConsensusHistogram", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowConsensusHistogram()) { return null; } + return (target.getShowConsensusHistogram() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowConsensusHistogram(); + return; + } + target.setShowConsensusHistogram( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showConsensusHistogram + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _showSequenceLogo + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showSequenceLogo", "showSequenceLogo", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasShowSequenceLogo()) { return null; } + return (target.getShowSequenceLogo() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteShowSequenceLogo(); + return; + } + target.setShowSequenceLogo( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _showSequenceLogo + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _normaliseSequenceLogo + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_normaliseSequenceLogo", "normaliseSequenceLogo", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasNormaliseSequenceLogo()) { return null; } + return (target.getNormaliseSequenceLogo() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteNormaliseSequenceLogo(); + return; + } + target.setNormaliseSequenceLogo( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _normaliseSequenceLogo + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _ignoreGapsinConsensus + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_ignoreGapsinConsensus", "ignoreGapsinConsensus", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasIgnoreGapsinConsensus()) { return null; } + return (target.getIgnoreGapsinConsensus() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteIgnoreGapsinConsensus(); + return; + } + target.setIgnoreGapsinConsensus( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _ignoreGapsinConsensus + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _startRes + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_startRes", "startRes", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasStartRes()) { return null; } + return new java.lang.Integer(target.getStartRes()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteStartRes(); + return; + } + target.setStartRes( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _startRes + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _startSeq + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_startSeq", "startSeq", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasStartSeq()) { return null; } + return new java.lang.Integer(target.getStartSeq()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteStartSeq(); + return; + } + target.setStartSeq( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _startSeq + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _fontName + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_fontName", "fontName", org.exolab.castor.xml.NodeType.Attribute); + desc.setImmutable(true); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getFontName(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.setFontName( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _fontName + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.StringValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.StringValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setWhiteSpace("preserve"); + } + desc.setValidator(fieldValidator); + //-- _fontSize + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_fontSize", "fontSize", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasFontSize()) { return null; } + return new java.lang.Integer(target.getFontSize()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteFontSize(); + return; + } + target.setFontSize( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _fontSize + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _fontStyle + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_fontStyle", "fontStyle", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasFontStyle()) { return null; } + return new java.lang.Integer(target.getFontStyle()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteFontStyle(); + return; + } + target.setFontStyle( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _fontStyle + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _viewName + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_viewName", "viewName", org.exolab.castor.xml.NodeType.Attribute); + desc.setImmutable(true); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getViewName(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.setViewName( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _viewName + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.StringValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.StringValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setWhiteSpace("preserve"); + } + desc.setValidator(fieldValidator); + //-- _sequenceSetId + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_sequenceSetId", "sequenceSetId", org.exolab.castor.xml.NodeType.Attribute); + desc.setImmutable(true); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getSequenceSetId(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.setSequenceSetId( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _sequenceSetId + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.StringValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.StringValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setWhiteSpace("preserve"); + } + desc.setValidator(fieldValidator); + //-- _gatheredViews + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_gatheredViews", "gatheredViews", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasGatheredViews()) { return null; } + return (target.getGatheredViews() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteGatheredViews(); + return; + } + target.setGatheredViews( ((java.lang.Boolean) value).booleanValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _gatheredViews + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.BooleanValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _textCol1 + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_textCol1", "textCol1", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasTextCol1()) { return null; } + return new java.lang.Integer(target.getTextCol1()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteTextCol1(); + return; + } + target.setTextCol1( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _textCol1 + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _textCol2 + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_textCol2", "textCol2", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasTextCol2()) { return null; } + return new java.lang.Integer(target.getTextCol2()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteTextCol2(); + return; + } + target.setTextCol2( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _textCol2 + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _textColThreshold + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_textColThreshold", "textColThreshold", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasTextColThreshold()) { return null; } + return new java.lang.Integer(target.getTextColThreshold()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteTextColThreshold(); + return; + } + target.setTextColThreshold( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _textColThreshold + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _id + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_id", "id", org.exolab.castor.xml.NodeType.Attribute); + super.setIdentity(desc); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getId(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.setId( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return new java.lang.String(); + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _id + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IdValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IdValidator(); + fieldValidator.setValidator(typeValidator); + } + desc.setValidator(fieldValidator); + //-- _complementId + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_complementId", "complementId", org.exolab.castor.xml.NodeType.Attribute); + desc.setImmutable(true); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getComplementId(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.setComplementId( (java.lang.String) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _complementId + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.StringValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.StringValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setWhiteSpace("preserve"); + } + desc.setValidator(fieldValidator); + //-- _width + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_width", "width", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasWidth()) { return null; } + return new java.lang.Integer(target.getWidth()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteWidth(); + return; + } + target.setWidth( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _width + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _height + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_height", "height", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasHeight()) { return null; } + return new java.lang.Integer(target.getHeight()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteHeight(); + return; + } + target.setHeight( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _height + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _xpos + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_xpos", "xpos", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasXpos()) { return null; } + return new java.lang.Integer(target.getXpos()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteXpos(); + return; + } + target.setXpos( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _xpos + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- _ypos + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_ypos", "ypos", org.exolab.castor.xml.NodeType.Attribute); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + if (!target.hasYpos()) { return null; } + return new java.lang.Integer(target.getYpos()); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + // if null, use delete method for optional primitives + if (value == null) { + target.deleteYpos(); + return; + } + target.setYpos( ((java.lang.Integer) value).intValue()); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return null; + } + }; + desc.setHandler(handler); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _ypos + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + org.exolab.castor.xml.validators.IntValidator typeValidator; + typeValidator = new org.exolab.castor.xml.validators.IntValidator(); + fieldValidator.setValidator(typeValidator); + typeValidator.setMinInclusive(-2147483648); + typeValidator.setMaxInclusive(2147483647); + } + desc.setValidator(fieldValidator); + //-- initialize element descriptors + + //-- _annotationColours + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(jalview.schemabinding.version2.AnnotationColours.class, "_annotationColours", "AnnotationColours", org.exolab.castor.xml.NodeType.Element); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getAnnotationColours(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.setAnnotationColours( (jalview.schemabinding.version2.AnnotationColours) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return new jalview.schemabinding.version2.AnnotationColours(); + } + }; + desc.setHandler(handler); + desc.setNameSpaceURI("www.jalview.org"); + desc.setMultivalued(false); + addFieldDescriptor(desc); + + //-- validation code for: _annotationColours + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + { //-- local scope + } + desc.setValidator(fieldValidator); + //-- _hiddenColumnsList + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(jalview.schemabinding.version2.HiddenColumns.class, "_hiddenColumnsList", "hiddenColumns", org.exolab.castor.xml.NodeType.Element); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getHiddenColumns(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.addHiddenColumns( (jalview.schemabinding.version2.HiddenColumns) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public void resetValue(Object object) throws IllegalStateException, IllegalArgumentException { + try { + Viewport target = (Viewport) object; + target.removeAllHiddenColumns(); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return new jalview.schemabinding.version2.HiddenColumns(); + } + }; + desc.setHandler(handler); + desc.setNameSpaceURI("www.jalview.org"); + desc.setMultivalued(true); + addFieldDescriptor(desc); + + //-- validation code for: _hiddenColumnsList + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + fieldValidator.setMinOccurs(0); + { //-- local scope + } + desc.setValidator(fieldValidator); + //-- _calcIdParamList + desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(jalview.schemabinding.version2.CalcIdParam.class, "_calcIdParamList", "calcIdParam", org.exolab.castor.xml.NodeType.Element); + handler = new org.exolab.castor.xml.XMLFieldHandler() { + public java.lang.Object getValue( java.lang.Object object ) + throws IllegalStateException + { + Viewport target = (Viewport) object; + return target.getCalcIdParam(); + } + public void setValue( java.lang.Object object, java.lang.Object value) + throws IllegalStateException, IllegalArgumentException + { + try { + Viewport target = (Viewport) object; + target.addCalcIdParam( (jalview.schemabinding.version2.CalcIdParam) value); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public void resetValue(Object object) throws IllegalStateException, IllegalArgumentException { + try { + Viewport target = (Viewport) object; + target.removeAllCalcIdParam(); + } catch (java.lang.Exception ex) { + throw new IllegalStateException(ex.toString()); + } + } + public java.lang.Object newInstance(java.lang.Object parent) { + return new jalview.schemabinding.version2.CalcIdParam(); + } + }; + desc.setHandler(handler); + desc.setNameSpaceURI("www.jalview.org"); + desc.setMultivalued(true); + addFieldDescriptor(desc); + + //-- validation code for: _calcIdParamList + fieldValidator = new org.exolab.castor.xml.FieldValidator(); + fieldValidator.setMinOccurs(0); + { //-- local scope + } + desc.setValidator(fieldValidator); } - desc.setValidator(fieldValidator); - // -- _pidSelected - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_pidSelected", "pidSelected", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasPidSelected()) - { - return null; - } - return (target.getPidSelected() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deletePidSelected(); - return; - } - target.setPidSelected(((java.lang.Boolean) value).booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - // -- validation code for: _pidSelected - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _bgColour - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.String.class, "_bgColour", "bgColour", - org.exolab.castor.xml.NodeType.Attribute); - desc.setImmutable(true); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getBgColour(); - } - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.setBgColour((java.lang.String) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } + //-----------/ + //- Methods -/ + //-----------/ - public java.lang.Object newInstance(java.lang.Object parent) - { + /** + * Method getAccessMode. + * + * @return the access mode specified for this class. + */ + public org.exolab.castor.mapping.AccessMode getAccessMode( + ) { return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _bgColour - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.StringValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.StringValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setWhiteSpace("preserve"); } - desc.setValidator(fieldValidator); - // -- _consThreshold - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_consThreshold", "consThreshold", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasConsThreshold()) - { - return null; - } - return new java.lang.Integer(target.getConsThreshold()); - } - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteConsThreshold(); - return; - } - target.setConsThreshold(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _consThreshold - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); + /** + * Method getIdentity. + * + * @return the identity field, null if this class has no + * identity. + */ + public org.exolab.castor.mapping.FieldDescriptor getIdentity( + ) { + return super.getIdentity(); } - desc.setValidator(fieldValidator); - // -- _pidThreshold - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_pidThreshold", "pidThreshold", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasPidThreshold()) - { - return null; - } - return new java.lang.Integer(target.getPidThreshold()); - } - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deletePidThreshold(); - return; - } - target.setPidThreshold(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _pidThreshold - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); + /** + * Method getJavaClass. + * + * @return the Java class represented by this descriptor. + */ + public java.lang.Class getJavaClass( + ) { + return jalview.schemabinding.version2.Viewport.class; } - desc.setValidator(fieldValidator); - // -- _title - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.String.class, "_title", "title", - org.exolab.castor.xml.NodeType.Attribute); - desc.setImmutable(true); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getTitle(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.setTitle((java.lang.String) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - // -- validation code for: _title - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.StringValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.StringValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setWhiteSpace("preserve"); + /** + * Method getNameSpacePrefix. + * + * @return the namespace prefix to use when marshaling as XML. + */ + public java.lang.String getNameSpacePrefix( + ) { + return _nsPrefix; } - desc.setValidator(fieldValidator); - // -- _showFullId - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showFullId", "showFullId", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowFullId()) - { - return null; - } - return (target.getShowFullId() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowFullId(); - return; - } - target.setShowFullId(((java.lang.Boolean) value).booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showFullId - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _rightAlignIds - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_rightAlignIds", "rightAlignIds", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasRightAlignIds()) - { - return null; - } - return (target.getRightAlignIds() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteRightAlignIds(); - return; - } - target.setRightAlignIds(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _rightAlignIds - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); + /** + * Method getNameSpaceURI. + * + * @return the namespace URI used when marshaling and + * unmarshaling as XML. + */ + public java.lang.String getNameSpaceURI( + ) { + return _nsURI; } - desc.setValidator(fieldValidator); - // -- _showText - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showText", "showText", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowText()) - { - return null; - } - return (target.getShowText() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowText(); - return; - } - target.setShowText(((java.lang.Boolean) value).booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - // -- validation code for: _showText - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); + /** + * Method getValidator. + * + * @return a specific validator for the class described by this + * ClassDescriptor. + */ + public org.exolab.castor.xml.TypeValidator getValidator( + ) { + return this; } - desc.setValidator(fieldValidator); - // -- _showColourText - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showColourText", "showColourText", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowColourText()) - { - return null; - } - return (target.getShowColourText() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowColourText(); - return; - } - target.setShowColourText(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - // -- validation code for: _showColourText - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); + /** + * Method getXMLName. + * + * @return the XML Name for the Class being described. + */ + public java.lang.String getXMLName( + ) { + return _xmlName; } - desc.setValidator(fieldValidator); - // -- _showUnconserved - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showUnconserved", "showUnconserved", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowUnconserved()) - { - return null; - } - return (target.getShowUnconserved() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowUnconserved(); - return; - } - target.setShowUnconserved(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showUnconserved - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showBoxes - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showBoxes", "showBoxes", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowBoxes()) - { - return null; - } - return (target.getShowBoxes() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowBoxes(); - return; - } - target.setShowBoxes(((java.lang.Boolean) value).booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showBoxes - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _wrapAlignment - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_wrapAlignment", "wrapAlignment", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasWrapAlignment()) - { - return null; - } - return (target.getWrapAlignment() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteWrapAlignment(); - return; - } - target.setWrapAlignment(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - // -- validation code for: _wrapAlignment - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); + /** + * Method isElementDefinition. + * + * @return true if XML schema definition of this Class is that + * of a global + * element or element with anonymous type definition. + */ + public boolean isElementDefinition( + ) { + return _elementDefinition; } - desc.setValidator(fieldValidator); - // -- _renderGaps - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_renderGaps", "renderGaps", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasRenderGaps()) - { - return null; - } - return (target.getRenderGaps() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteRenderGaps(); - return; - } - target.setRenderGaps(((java.lang.Boolean) value).booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _renderGaps - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showSequenceFeatures - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showSequenceFeatures", - "showSequenceFeatures", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowSequenceFeatures()) - { - return null; - } - return (target.getShowSequenceFeatures() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowSequenceFeatures(); - return; - } - target.setShowSequenceFeatures(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showSequenceFeatures - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showNPfeatureTooltip - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showNPfeatureTooltip", - "showNPfeatureTooltip", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowNPfeatureTooltip()) - { - return null; - } - return (target.getShowNPfeatureTooltip() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowNPfeatureTooltip(); - return; - } - target.setShowNPfeatureTooltip(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showNPfeatureTooltip - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showDbRefTooltip - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showDbRefTooltip", - "showDbRefTooltip", org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowDbRefTooltip()) - { - return null; - } - return (target.getShowDbRefTooltip() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowDbRefTooltip(); - return; - } - target.setShowDbRefTooltip(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showDbRefTooltip - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _followHighlight - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_followHighlight", "followHighlight", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasFollowHighlight()) - { - return null; - } - return (target.getFollowHighlight() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteFollowHighlight(); - return; - } - target.setFollowHighlight(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _followHighlight - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _followSelection - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_followSelection", "followSelection", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasFollowSelection()) - { - return null; - } - return (target.getFollowSelection() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteFollowSelection(); - return; - } - target.setFollowSelection(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _followSelection - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showAnnotation - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showAnnotation", "showAnnotation", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowAnnotation()) - { - return null; - } - return (target.getShowAnnotation() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowAnnotation(); - return; - } - target.setShowAnnotation(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showAnnotation - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _centreColumnLabels - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_centreColumnLabels", - "centreColumnLabels", org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasCentreColumnLabels()) - { - return null; - } - return (target.getCentreColumnLabels() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteCentreColumnLabels(); - return; - } - target.setCentreColumnLabels(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _centreColumnLabels - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showGroupConservation - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showGroupConservation", - "showGroupConservation", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowGroupConservation()) - { - return null; - } - return (target.getShowGroupConservation() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowGroupConservation(); - return; - } - target.setShowGroupConservation(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showGroupConservation - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showGroupConsensus - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showGroupConsensus", - "showGroupConsensus", org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowGroupConsensus()) - { - return null; - } - return (target.getShowGroupConsensus() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowGroupConsensus(); - return; - } - target.setShowGroupConsensus(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showGroupConsensus - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showConsensusHistogram - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showConsensusHistogram", - "showConsensusHistogram", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowConsensusHistogram()) - { - return null; - } - return (target.getShowConsensusHistogram() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowConsensusHistogram(); - return; - } - target.setShowConsensusHistogram(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showConsensusHistogram - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _showSequenceLogo - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_showSequenceLogo", - "showSequenceLogo", org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasShowSequenceLogo()) - { - return null; - } - return (target.getShowSequenceLogo() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteShowSequenceLogo(); - return; - } - target.setShowSequenceLogo(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _showSequenceLogo - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _normaliseSequenceLogo - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_normaliseSequenceLogo", - "normaliseSequenceLogo", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasNormaliseSequenceLogo()) - { - return null; - } - return (target.getNormaliseSequenceLogo() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteNormaliseSequenceLogo(); - return; - } - target.setNormaliseSequenceLogo(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _normaliseSequenceLogo - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _ignoreGapsinConsensus - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_ignoreGapsinConsensus", - "ignoreGapsinConsensus", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasIgnoreGapsinConsensus()) - { - return null; - } - return (target.getIgnoreGapsinConsensus() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteIgnoreGapsinConsensus(); - return; - } - target.setIgnoreGapsinConsensus(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _ignoreGapsinConsensus - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _startRes - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_startRes", "startRes", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasStartRes()) - { - return null; - } - return new java.lang.Integer(target.getStartRes()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteStartRes(); - return; - } - target.setStartRes(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _startRes - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _startSeq - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_startSeq", "startSeq", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasStartSeq()) - { - return null; - } - return new java.lang.Integer(target.getStartSeq()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteStartSeq(); - return; - } - target.setStartSeq(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _startSeq - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _fontName - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.String.class, "_fontName", "fontName", - org.exolab.castor.xml.NodeType.Attribute); - desc.setImmutable(true); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getFontName(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.setFontName((java.lang.String) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _fontName - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.StringValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.StringValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setWhiteSpace("preserve"); - } - desc.setValidator(fieldValidator); - // -- _fontSize - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_fontSize", "fontSize", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasFontSize()) - { - return null; - } - return new java.lang.Integer(target.getFontSize()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteFontSize(); - return; - } - target.setFontSize(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _fontSize - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _fontStyle - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_fontStyle", "fontStyle", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasFontStyle()) - { - return null; - } - return new java.lang.Integer(target.getFontStyle()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteFontStyle(); - return; - } - target.setFontStyle(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _fontStyle - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _viewName - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.String.class, "_viewName", "viewName", - org.exolab.castor.xml.NodeType.Attribute); - desc.setImmutable(true); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getViewName(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.setViewName((java.lang.String) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _viewName - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.StringValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.StringValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setWhiteSpace("preserve"); - } - desc.setValidator(fieldValidator); - // -- _sequenceSetId - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.String.class, "_sequenceSetId", "sequenceSetId", - org.exolab.castor.xml.NodeType.Attribute); - desc.setImmutable(true); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getSequenceSetId(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.setSequenceSetId((java.lang.String) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _sequenceSetId - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.StringValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.StringValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setWhiteSpace("preserve"); - } - desc.setValidator(fieldValidator); - // -- _gatheredViews - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Boolean.TYPE, "_gatheredViews", "gatheredViews", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasGatheredViews()) - { - return null; - } - return (target.getGatheredViews() ? java.lang.Boolean.TRUE - : java.lang.Boolean.FALSE); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteGatheredViews(); - return; - } - target.setGatheredViews(((java.lang.Boolean) value) - .booleanValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _gatheredViews - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.BooleanValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.BooleanValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _textCol1 - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_textCol1", "textCol1", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasTextCol1()) - { - return null; - } - return new java.lang.Integer(target.getTextCol1()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteTextCol1(); - return; - } - target.setTextCol1(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _textCol1 - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _textCol2 - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_textCol2", "textCol2", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasTextCol2()) - { - return null; - } - return new java.lang.Integer(target.getTextCol2()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteTextCol2(); - return; - } - target.setTextCol2(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _textCol2 - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _textColThreshold - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_textColThreshold", - "textColThreshold", org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasTextColThreshold()) - { - return null; - } - return new java.lang.Integer(target.getTextColThreshold()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteTextColThreshold(); - return; - } - target.setTextColThreshold(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _textColThreshold - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _id - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.String.class, "_id", "id", - org.exolab.castor.xml.NodeType.Attribute); - super.setIdentity(desc); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getId(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.setId((java.lang.String) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return new java.lang.String(); - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _id - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IdValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IdValidator(); - fieldValidator.setValidator(typeValidator); - } - desc.setValidator(fieldValidator); - // -- _width - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_width", "width", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasWidth()) - { - return null; - } - return new java.lang.Integer(target.getWidth()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteWidth(); - return; - } - target.setWidth(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _width - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _height - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_height", "height", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasHeight()) - { - return null; - } - return new java.lang.Integer(target.getHeight()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteHeight(); - return; - } - target.setHeight(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _height - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _xpos - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_xpos", "xpos", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasXpos()) - { - return null; - } - return new java.lang.Integer(target.getXpos()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteXpos(); - return; - } - target.setXpos(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _xpos - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- _ypos - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - java.lang.Integer.TYPE, "_ypos", "ypos", - org.exolab.castor.xml.NodeType.Attribute); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - if (!target.hasYpos()) - { - return null; - } - return new java.lang.Integer(target.getYpos()); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - // if null, use delete method for optional primitives - if (value == null) - { - target.deleteYpos(); - return; - } - target.setYpos(((java.lang.Integer) value).intValue()); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return null; - } - }; - desc.setHandler(handler); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _ypos - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - org.exolab.castor.xml.validators.IntValidator typeValidator; - typeValidator = new org.exolab.castor.xml.validators.IntValidator(); - fieldValidator.setValidator(typeValidator); - typeValidator.setMinInclusive(-2147483648); - typeValidator.setMaxInclusive(2147483647); - } - desc.setValidator(fieldValidator); - // -- initialize element descriptors - - // -- _annotationColours - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - jalview.schemabinding.version2.AnnotationColours.class, - "_annotationColours", "AnnotationColours", - org.exolab.castor.xml.NodeType.Element); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getAnnotationColours(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.setAnnotationColours((jalview.schemabinding.version2.AnnotationColours) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return new jalview.schemabinding.version2.AnnotationColours(); - } - }; - desc.setHandler(handler); - desc.setNameSpaceURI("www.jalview.org"); - desc.setMultivalued(false); - addFieldDescriptor(desc); - - // -- validation code for: _annotationColours - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - { // -- local scope - } - desc.setValidator(fieldValidator); - // -- _hiddenColumnsList - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - jalview.schemabinding.version2.HiddenColumns.class, - "_hiddenColumnsList", "hiddenColumns", - org.exolab.castor.xml.NodeType.Element); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getHiddenColumns(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.addHiddenColumns((jalview.schemabinding.version2.HiddenColumns) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public void resetValue(Object object) throws IllegalStateException, - IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.removeAllHiddenColumns(); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return new jalview.schemabinding.version2.HiddenColumns(); - } - }; - desc.setHandler(handler); - desc.setNameSpaceURI("www.jalview.org"); - desc.setMultivalued(true); - addFieldDescriptor(desc); - - // -- validation code for: _hiddenColumnsList - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - fieldValidator.setMinOccurs(0); - { // -- local scope - } - desc.setValidator(fieldValidator); - // -- _calcIdParamList - desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl( - jalview.schemabinding.version2.CalcIdParam.class, - "_calcIdParamList", "calcIdParam", - org.exolab.castor.xml.NodeType.Element); - handler = new org.exolab.castor.xml.XMLFieldHandler() - { - public java.lang.Object getValue(java.lang.Object object) - throws IllegalStateException - { - Viewport target = (Viewport) object; - return target.getCalcIdParam(); - } - - public void setValue(java.lang.Object object, java.lang.Object value) - throws IllegalStateException, IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.addCalcIdParam((jalview.schemabinding.version2.CalcIdParam) value); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public void resetValue(Object object) throws IllegalStateException, - IllegalArgumentException - { - try - { - Viewport target = (Viewport) object; - target.removeAllCalcIdParam(); - } catch (java.lang.Exception ex) - { - throw new IllegalStateException(ex.toString()); - } - } - - public java.lang.Object newInstance(java.lang.Object parent) - { - return new jalview.schemabinding.version2.CalcIdParam(); - } - }; - desc.setHandler(handler); - desc.setNameSpaceURI("www.jalview.org"); - desc.setMultivalued(true); - addFieldDescriptor(desc); - - // -- validation code for: _calcIdParamList - fieldValidator = new org.exolab.castor.xml.FieldValidator(); - fieldValidator.setMinOccurs(0); - { // -- local scope - } - desc.setValidator(fieldValidator); - } - - // -----------/ - // - Methods -/ - // -----------/ - - /** - * Method getAccessMode. - * - * @return the access mode specified for this class. - */ - public org.exolab.castor.mapping.AccessMode getAccessMode() - { - return null; - } - - /** - * Method getIdentity. - * - * @return the identity field, null if this class has no identity. - */ - public org.exolab.castor.mapping.FieldDescriptor getIdentity() - { - return super.getIdentity(); - } - - /** - * Method getJavaClass. - * - * @return the Java class represented by this descriptor. - */ - public java.lang.Class getJavaClass() - { - return jalview.schemabinding.version2.Viewport.class; - } - - /** - * Method getNameSpacePrefix. - * - * @return the namespace prefix to use when marshaling as XML. - */ - public java.lang.String getNameSpacePrefix() - { - return _nsPrefix; - } - - /** - * Method getNameSpaceURI. - * - * @return the namespace URI used when marshaling and unmarshaling as XML. - */ - public java.lang.String getNameSpaceURI() - { - return _nsURI; - } - - /** - * Method getValidator. - * - * @return a specific validator for the class described by this - * ClassDescriptor. - */ - public org.exolab.castor.xml.TypeValidator getValidator() - { - return this; - } - - /** - * Method getXMLName. - * - * @return the XML Name for the Class being described. - */ - public java.lang.String getXMLName() - { - return _xmlName; - } - - /** - * Method isElementDefinition. - * - * @return true if XML schema definition of this Class is that of a global - * element or element with anonymous type definition. - */ - public boolean isElementDefinition() - { - return _elementDefinition; - } } diff --git a/src/jalview/schemes/ClustalxColourScheme.java b/src/jalview/schemes/ClustalxColourScheme.java index d766596..ca4316f 100755 --- a/src/jalview/schemes/ClustalxColourScheme.java +++ b/src/jalview/schemes/ClustalxColourScheme.java @@ -25,41 +25,47 @@ import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceI; import java.awt.Color; -import java.util.Hashtable; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Vector; -public class ClustalxColourScheme extends ResidueColourScheme // implements -// IParameterizable +public class ClustalxColourScheme extends ResidueColourScheme { - public static Hashtable colhash = new Hashtable(); + private static final int EIGHTY_FIVE = 85; - Hashtable[] cons; + private static final int FIFTY = 50; - int[][] cons2; + private static final int EIGHTY = 80; - ConsensusColour[] colours; + private static final int SIXTY = 60; - ConsensusColour[] ResidueColour; + /* + * Map from conventional colour names to Clustal version of the same + */ + private static Map colhash = new HashMap(); + + private int[][] cons2; + + private ConsensusColour[] colours; - int size; + private ConsensusColour[] residueColour; - Consensus[] conses = new Consensus[32]; + private int size; - Vector colourTable = new Vector(); + private Consensus[] conses = new Consensus[32]; private boolean includeGaps = true; + static { - colhash.put("RED", new Color((float) 0.9, (float) 0.2, (float) 0.1)); - colhash.put("BLUE", new Color((float) 0.5, (float) 0.7, (float) 0.9)); - colhash.put("GREEN", new Color((float) 0.1, (float) 0.8, (float) 0.1)); - colhash.put("ORANGE", new Color((float) 0.9, (float) 0.6, (float) 0.3)); - colhash.put("CYAN", new Color((float) 0.1, (float) 0.7, (float) 0.7)); - colhash.put("PINK", new Color((float) 0.9, (float) 0.5, (float) 0.5)); - colhash.put("MAGENTA", new Color((float) 0.8, (float) 0.3, (float) 0.8)); - colhash.put("YELLOW", new Color((float) 0.8, (float) 0.8, (float) 0.0)); + colhash.put(Color.RED, new Color(0.9f, 0.2f, 0.1f)); + colhash.put(Color.BLUE, new Color(0.5f, 0.7f, 0.9f)); + colhash.put(Color.GREEN, new Color(0.1f, 0.8f, 0.1f)); + colhash.put(Color.ORANGE, new Color(0.9f, 0.6f, 0.3f)); + colhash.put(Color.CYAN, new Color(0.1f, 0.7f, 0.7f)); + colhash.put(Color.PINK, new Color(0.9f, 0.5f, 0.5f)); + colhash.put(Color.MAGENTA, new Color(0.8f, 0.3f, 0.8f)); + colhash.put(Color.YELLOW, new Color(0.8f, 0.8f, 0.0f)); } public ClustalxColourScheme(AnnotatedCollectionI alignment, @@ -122,36 +128,36 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements public void makeColours() { - conses[0] = new Consensus("WLVIMAFCYHP", 60); - conses[1] = new Consensus("WLVIMAFCYHP", 80); - conses[2] = new Consensus("ED", 50); - conses[3] = new Consensus("KR", 60); - conses[4] = new Consensus("G", 50); - conses[5] = new Consensus("N", 50); - conses[6] = new Consensus("QE", 50); - conses[7] = new Consensus("P", 50); - conses[8] = new Consensus("TS", 50); - - conses[26] = new Consensus("A", 85); - conses[27] = new Consensus("C", 85); - conses[10] = new Consensus("E", 85); - conses[11] = new Consensus("F", 85); - conses[12] = new Consensus("G", 85); - conses[13] = new Consensus("H", 85); - conses[14] = new Consensus("I", 85); - conses[15] = new Consensus("L", 85); - conses[16] = new Consensus("M", 85); - conses[17] = new Consensus("N", 85); - conses[18] = new Consensus("P", 85); - conses[19] = new Consensus("Q", 85); - conses[20] = new Consensus("R", 85); - conses[21] = new Consensus("S", 85); - conses[22] = new Consensus("T", 85); - conses[23] = new Consensus("V", 85); - conses[24] = new Consensus("W", 85); - conses[25] = new Consensus("Y", 85); - conses[28] = new Consensus("K", 85); - conses[29] = new Consensus("D", 85); + conses[0] = new Consensus("WLVIMAFCYHP", SIXTY); + conses[1] = new Consensus("WLVIMAFCYHP", EIGHTY); + conses[2] = new Consensus("ED", FIFTY); + conses[3] = new Consensus("KR", SIXTY); + conses[4] = new Consensus("G", FIFTY); + conses[5] = new Consensus("N", FIFTY); + conses[6] = new Consensus("QE", FIFTY); + conses[7] = new Consensus("P", FIFTY); + conses[8] = new Consensus("TS", FIFTY); + + conses[26] = new Consensus("A", EIGHTY_FIVE); + conses[27] = new Consensus("C", EIGHTY_FIVE); + conses[10] = new Consensus("E", EIGHTY_FIVE); + conses[11] = new Consensus("F", EIGHTY_FIVE); + conses[12] = new Consensus("G", EIGHTY_FIVE); + conses[13] = new Consensus("H", EIGHTY_FIVE); + conses[14] = new Consensus("I", EIGHTY_FIVE); + conses[15] = new Consensus("L", EIGHTY_FIVE); + conses[16] = new Consensus("M", EIGHTY_FIVE); + conses[17] = new Consensus("N", EIGHTY_FIVE); + conses[18] = new Consensus("P", EIGHTY_FIVE); + conses[19] = new Consensus("Q", EIGHTY_FIVE); + conses[20] = new Consensus("R", EIGHTY_FIVE); + conses[21] = new Consensus("S", EIGHTY_FIVE); + conses[22] = new Consensus("T", EIGHTY_FIVE); + conses[23] = new Consensus("V", EIGHTY_FIVE); + conses[24] = new Consensus("W", EIGHTY_FIVE); + conses[25] = new Consensus("Y", EIGHTY_FIVE); + conses[28] = new Consensus("K", EIGHTY_FIVE); + conses[29] = new Consensus("D", EIGHTY_FIVE); conses[30] = new Consensus("G", 0); conses[31] = new Consensus("P", 0); @@ -161,15 +167,15 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements Consensus[] tmp8 = new Consensus[1]; tmp8[0] = conses[30]; // G - colours[7] = new ConsensusColour((Color) colhash.get("ORANGE"), tmp8); + colours[7] = new ConsensusColour(colhash.get(Color.ORANGE), tmp8); Consensus[] tmp9 = new Consensus[1]; tmp9[0] = conses[31]; // P - colours[8] = new ConsensusColour((Color) colhash.get("YELLOW"), tmp9); + colours[8] = new ConsensusColour(colhash.get(Color.YELLOW), tmp9); Consensus[] tmp10 = new Consensus[1]; tmp10[0] = conses[27]; // C - colours[9] = new ConsensusColour((Color) colhash.get("PINK"), tmp8); + colours[9] = new ConsensusColour(colhash.get(Color.PINK), tmp8); Consensus[] tmp1 = new Consensus[14]; tmp1[0] = conses[0]; // % @@ -186,9 +192,9 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements tmp1[11] = conses[25]; // Y tmp1[12] = conses[18]; // P tmp1[13] = conses[19]; // p - colours[0] = new ConsensusColour((Color) colhash.get("BLUE"), tmp1); + colours[0] = new ConsensusColour(colhash.get(Color.BLUE), tmp1); - colours[10] = new ConsensusColour((Color) colhash.get("CYAN"), tmp1); + colours[10] = new ConsensusColour(colhash.get(Color.CYAN), tmp1); Consensus[] tmp2 = new Consensus[5]; tmp2[0] = conses[8]; // t @@ -196,14 +202,14 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements tmp2[2] = conses[22]; // T tmp2[3] = conses[0]; // % tmp2[4] = conses[1]; // # - colours[1] = new ConsensusColour((Color) colhash.get("GREEN"), tmp2); + colours[1] = new ConsensusColour(colhash.get(Color.GREEN), tmp2); Consensus[] tmp3 = new Consensus[3]; tmp3[0] = conses[17]; // N tmp3[1] = conses[29]; // D tmp3[2] = conses[5]; // n - colours[2] = new ConsensusColour((Color) colhash.get("GREEN"), tmp3); + colours[2] = new ConsensusColour(colhash.get(Color.GREEN), tmp3); Consensus[] tmp4 = new Consensus[6]; tmp4[0] = conses[6]; // q = QE @@ -212,14 +218,14 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements tmp4[3] = conses[3]; // + tmp4[4] = conses[28]; // K tmp4[5] = conses[20]; // R - colours[3] = new ConsensusColour((Color) colhash.get("GREEN"), tmp4); + colours[3] = new ConsensusColour(colhash.get(Color.GREEN), tmp4); Consensus[] tmp5 = new Consensus[4]; tmp5[0] = conses[3]; // + tmp5[1] = conses[28]; // K tmp5[2] = conses[20]; // R tmp5[3] = conses[19]; // Q - colours[4] = new ConsensusColour((Color) colhash.get("RED"), tmp5); + colours[4] = new ConsensusColour(colhash.get(Color.RED), tmp5); Consensus[] tmp6 = new Consensus[6]; tmp6[0] = conses[3]; // - @@ -228,7 +234,7 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements tmp6[3] = conses[6]; // QE tmp6[4] = conses[19]; // Q tmp6[5] = conses[2]; // DE - colours[5] = new ConsensusColour((Color) colhash.get("MAGENTA"), tmp6); + colours[5] = new ConsensusColour(colhash.get(Color.MAGENTA), tmp6); Consensus[] tmp7 = new Consensus[5]; tmp7[0] = conses[3]; // - @@ -236,30 +242,30 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements tmp7[2] = conses[10]; // E tmp7[3] = conses[17]; // N tmp7[4] = conses[2]; // DE - colours[6] = new ConsensusColour((Color) colhash.get("MAGENTA"), tmp7); + colours[6] = new ConsensusColour(colhash.get(Color.MAGENTA), tmp7); // Now attach the ConsensusColours to the residue letters - ResidueColour = new ConsensusColour[20]; - ResidueColour[0] = colours[0]; // A - ResidueColour[1] = colours[4]; // R - ResidueColour[2] = colours[2]; // N - ResidueColour[3] = colours[6]; // D - ResidueColour[4] = colours[0]; // C - ResidueColour[5] = colours[3]; // Q - ResidueColour[6] = colours[5]; // E - ResidueColour[7] = colours[7]; // G - ResidueColour[8] = colours[10]; // H - ResidueColour[9] = colours[0]; // I - ResidueColour[10] = colours[0]; // L - ResidueColour[11] = colours[4]; // K - ResidueColour[12] = colours[0]; // M - ResidueColour[13] = colours[0]; // F - ResidueColour[14] = colours[8]; // P - ResidueColour[15] = colours[1]; // S - ResidueColour[16] = colours[1]; // T - ResidueColour[17] = colours[0]; // W - ResidueColour[18] = colours[10]; // Y - ResidueColour[19] = colours[0]; // V + residueColour = new ConsensusColour[20]; + residueColour[0] = colours[0]; // A + residueColour[1] = colours[4]; // R + residueColour[2] = colours[2]; // N + residueColour[3] = colours[6]; // D + residueColour[4] = colours[0]; // C + residueColour[5] = colours[3]; // Q + residueColour[6] = colours[5]; // E + residueColour[7] = colours[7]; // G + residueColour[8] = colours[10]; // H + residueColour[9] = colours[0]; // I + residueColour[10] = colours[0]; // L + residueColour[11] = colours[4]; // K + residueColour[12] = colours[0]; // M + residueColour[13] = colours[0]; // F + residueColour[14] = colours[8]; // P + residueColour[15] = colours[1]; // S + residueColour[16] = colours[1]; // T + residueColour[17] = colours[0]; // W + residueColour[18] = colours[10]; // Y + residueColour[19] = colours[0]; // V } @Override @@ -288,12 +294,12 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements return currentColour; } - for (int k = 0; k < ResidueColour[i].conses.length; k++) + for (int k = 0; k < residueColour[i].conses.length; k++) { - if (ResidueColour[i].conses[k].isConserved(cons2, j, size, + if (residueColour[i].conses[k].isConserved(cons2, j, size, includeGaps)) { - currentColour = ResidueColour[i].c; + currentColour = residueColour[i].c; } } @@ -301,7 +307,7 @@ public class ClustalxColourScheme extends ResidueColourScheme // implements { if (conses[27].isConserved(cons2, j, size, includeGaps)) { - currentColour = (Color) colhash.get("PINK"); + currentColour = colhash.get(Color.PINK); } } diff --git a/src/jalview/schemes/ResidueProperties.java b/src/jalview/schemes/ResidueProperties.java index 593e83d..0f34824 100755 --- a/src/jalview/schemes/ResidueProperties.java +++ b/src/jalview/schemes/ResidueProperties.java @@ -27,6 +27,7 @@ import jalview.api.analysis.ScoreModelI; import java.awt.Color; import java.util.ArrayList; import java.util.Enumeration; +import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; @@ -43,11 +44,11 @@ public class ResidueProperties public static final int[] purinepyrimidineIndex; - public static final Hashtable aa3Hash = new Hashtable(); + public static final Map aa3Hash = new HashMap(); - public static final Hashtable aa2Triplet = new Hashtable(); + public static final Map aa2Triplet = new HashMap(); - public static final Hashtable nucleotideName = new Hashtable(); + public static final Map nucleotideName = new HashMap(); static { @@ -632,49 +633,51 @@ public class ResidueProperties public static final float[] pidThresholds = { 80, 60, 40, }; - public static Hashtable codonHash = new Hashtable(); + public static Map> codonHash = new HashMap>(); - public static Vector Lys = new Vector(); + private static List Lys = new ArrayList(); - public static Vector Asn = new Vector(); + private static List Asn = new ArrayList(); - public static Vector Gln = new Vector(); + private static List Gln = new ArrayList(); - public static Vector His = new Vector(); + private static List His = new ArrayList(); - public static Vector Glu = new Vector(); + private static List Glu = new ArrayList(); - public static Vector Asp = new Vector(); + private static List Asp = new ArrayList(); - public static Vector Tyr = new Vector(); + private static List Tyr = new ArrayList(); - public static Vector Thr = new Vector(); + private static List Thr = new ArrayList(); - public static Vector Pro = new Vector(); + private static List Pro = new ArrayList(); - public static Vector Ala = new Vector(); + private static List Ala = new ArrayList(); - public static Vector Ser = new Vector(); + private static List Ser = new ArrayList(); - public static Vector Arg = new Vector(); + private static List Arg = new ArrayList(); - public static Vector Gly = new Vector(); + private static List Gly = new ArrayList(); - public static Vector Trp = new Vector(); + private static List Trp = new ArrayList(); - public static Vector Cys = new Vector(); + private static List Cys = new ArrayList(); - public static Vector Ile = new Vector(); + private static List Ile = new ArrayList(); - public static Vector Met = new Vector(); + private static List Met = new ArrayList(); - public static Vector Leu = new Vector(); + private static List Leu = new ArrayList(); - public static Vector Val = new Vector(); + private static List Val = new ArrayList(); - public static Vector Phe = new Vector(); + private static List Phe = new ArrayList(); - public static Vector STOP = new Vector(); + public static List STOP = new ArrayList(); + + public static String START = "ATG"; static { @@ -704,7 +707,7 @@ public class ResidueProperties /** * Nucleotide Ambiguity Codes */ - public static final Hashtable ambiguityCodes = new Hashtable(); + public static final Map ambiguityCodes = new Hashtable(); /** * Codon triplets with additional symbols for unambiguous codons that include @@ -719,105 +722,32 @@ public class ResidueProperties static { - /** - * 3.2. Purine (adenine or guanine): R - * - * R is the symbol previously recommended [1]. + /* + * Ambiguity codes as per http://www.chem.qmul.ac.uk/iubmb/misc/naseq.html */ ambiguityCodes.put("R", new String[] { "A", "G" }); - - /** - * 3.3. Pyrimidine (thymine or cytosine): Y - * - * Y is the symbol previously recommended [1]. - */ ambiguityCodes.put("Y", new String[] { "T", "C" }); - /** - * 3.4. Adenine or thymine: W - * - * Although several diverse symbols have been used for this pair, (and for - * the reciprocal pair G+C), only two symbols have a rational basis, L and - * W: L derives from DNA density (light; G+C - heavy - would thus be H); W - * derives from the strength of the hydrogen bonding interaction between the - * base pairs (weak for A+T: G +C - strong - would thus be S). However, the - * system recommended for the three-base series (not-A = B, etc., see below, - * section 3.8) rules out H as this would be not-G. W is thus recommended. - */ ambiguityCodes.put("W", new String[] { "A", "T" }); - /** - * 3.5. Guanine or cytosine: S - * - * The choice of this symbol is discussed above in section 3.4. - */ ambiguityCodes.put("S", new String[] { "G", "C" }); - /** - * 3.6. Adenine or cytosine: M - * - * There are few common features between A and C. The presence of an NH2 - * group in similar positions on both bases (Fig. 1) makes possible a - * logically derived symbol. A and N being ruled out, M (from aMino) is - * recommended. - * - * - * Fig. 1. Origin of the symbols M and K The four bases are drawn so as to - * show the relationship between adenine and cytosine on the one hand, which - * both have aMino groups at the ring position most distant from the point - * of attachment to the sugar, and between guanine and thymine on the other, - * which both have Keto groups at the corresponding position. The ring atoms - * are numbered as recommended [24-26], although for the present purpose - * this has the disadvantage of giving discordant numbers to the - * corresponding positions. - */ ambiguityCodes.put("M", new String[] { "A", "C" }); - /** - * 3.7. Guanine or thymine: K By analogy with A and C (section 3.6), both G - * and T have Keto groups in similar positions (Fig. 1). - */ ambiguityCodes.put("K", new String[] { "G", "T" }); - /** - * 3.8. Adenine or thymine or cytosine: H - * - * Not-G is the most simple means of memorising this combination and symbols - * logically related to G were examined. F and H would both be suitable, as - * the letters before and after G in the alphabet, but A would have no - * equivalent to F. The use of H has historical precedence [2]. - */ ambiguityCodes.put("H", new String[] { "A", "T", "C" }); - /** - * 3.9. Guanine or cytosine or thymine: B - * - * Not-A as above (section 3.8). - */ ambiguityCodes.put("B", new String[] { "G", "T", "C" }); - /** - * 3.10. Guanine or adenine or cytosine: V - * - * Not-T by analogy with not-G (section 3.8) would be U but this is ruled - * out to eliminate confusion with uracil. V is the next logical choice. - * Note that T and U may in some cases be considered to be synonyms. - */ ambiguityCodes.put("V", new String[] { "G", "A", "C" }); - /** - * 3.11. Guanine or adenine or thymine: D - * - * Not-C as above (section 3.8). - */ ambiguityCodes.put("D", new String[] { "G", "A", "T" }); - /** - * 3.12. Guanine or adenine or thymine or cytosine: N - */ - ambiguityCodes.put("R", new String[] + ambiguityCodes.put("N", new String[] { "G", "A", "T", "C" }); + // Now build codon translation table codonHash2.put("AAA", "K"); codonHash2.put("AAG", "K"); @@ -1044,87 +974,87 @@ public class ResidueProperties static { - Lys.addElement("AAA"); - Lys.addElement("AAG"); - Asn.addElement("AAC"); - Asn.addElement("AAT"); - - Gln.addElement("CAA"); - Gln.addElement("CAG"); - His.addElement("CAC"); - His.addElement("CAT"); - - Glu.addElement("GAA"); - Glu.addElement("GAG"); - Asp.addElement("GAC"); - Asp.addElement("GAT"); - - Tyr.addElement("TAC"); - Tyr.addElement("TAT"); - - Thr.addElement("ACA"); - Thr.addElement("ACG"); - Thr.addElement("ACC"); - Thr.addElement("ACT"); - - Pro.addElement("CCA"); - Pro.addElement("CCG"); - Pro.addElement("CCC"); - Pro.addElement("CCT"); - - Ala.addElement("GCA"); - Ala.addElement("GCG"); - Ala.addElement("GCC"); - Ala.addElement("GCT"); - - Ser.addElement("TCA"); - Ser.addElement("TCG"); - Ser.addElement("TCC"); - Ser.addElement("TCT"); - Ser.addElement("AGC"); - Ser.addElement("AGT"); - - Arg.addElement("AGA"); - Arg.addElement("AGG"); - Arg.addElement("CGA"); - Arg.addElement("CGG"); - Arg.addElement("CGC"); - Arg.addElement("CGT"); - - Gly.addElement("GGA"); - Gly.addElement("GGG"); - Gly.addElement("GGC"); - Gly.addElement("GGT"); - - STOP.addElement("TGA"); - STOP.addElement("TAA"); - STOP.addElement("TAG"); - - Trp.addElement("TGG"); - - Cys.addElement("TGC"); - Cys.addElement("TGT"); - - Ile.addElement("ATA"); - Ile.addElement("ATC"); - Ile.addElement("ATT"); - - Met.addElement("ATG"); - - Leu.addElement("CTA"); - Leu.addElement("CTG"); - Leu.addElement("CTC"); - Leu.addElement("CTT"); - Leu.addElement("TTA"); - Leu.addElement("TTG"); - - Val.addElement("GTA"); - Val.addElement("GTG"); - Val.addElement("GTC"); - Val.addElement("GTT"); - - Phe.addElement("TTC"); - Phe.addElement("TTT"); + Lys.add("AAA"); + Lys.add("AAG"); + Asn.add("AAC"); + Asn.add("AAT"); + + Gln.add("CAA"); + Gln.add("CAG"); + His.add("CAC"); + His.add("CAT"); + + Glu.add("GAA"); + Glu.add("GAG"); + Asp.add("GAC"); + Asp.add("GAT"); + + Tyr.add("TAC"); + Tyr.add("TAT"); + + Thr.add("ACA"); + Thr.add("ACG"); + Thr.add("ACC"); + Thr.add("ACT"); + + Pro.add("CCA"); + Pro.add("CCG"); + Pro.add("CCC"); + Pro.add("CCT"); + + Ala.add("GCA"); + Ala.add("GCG"); + Ala.add("GCC"); + Ala.add("GCT"); + + Ser.add("TCA"); + Ser.add("TCG"); + Ser.add("TCC"); + Ser.add("TCT"); + Ser.add("AGC"); + Ser.add("AGT"); + + Arg.add("AGA"); + Arg.add("AGG"); + Arg.add("CGA"); + Arg.add("CGG"); + Arg.add("CGC"); + Arg.add("CGT"); + + Gly.add("GGA"); + Gly.add("GGG"); + Gly.add("GGC"); + Gly.add("GGT"); + + STOP.add("TGA"); + STOP.add("TAA"); + STOP.add("TAG"); + + Trp.add("TGG"); + + Cys.add("TGC"); + Cys.add("TGT"); + + Ile.add("ATA"); + Ile.add("ATC"); + Ile.add("ATT"); + + Met.add("ATG"); + + Leu.add("CTA"); + Leu.add("CTG"); + Leu.add("CTC"); + Leu.add("CTT"); + Leu.add("TTA"); + Leu.add("TTG"); + + Val.add("GTA"); + Val.add("GTG"); + Val.add("GTC"); + Val.add("GTT"); + + Phe.add("TTC"); + Phe.add("TTT"); } // Stores residue codes/names and colours and other things @@ -1521,7 +1451,7 @@ public class ResidueProperties return hyd; } - public static Hashtable getAA3Hash() + public static Map getAA3Hash() { return aa3Hash; } @@ -1591,14 +1521,9 @@ public class ResidueProperties { return "X"; } - Enumeration e = codonHash.keys(); - - while (e.hasMoreElements()) + for (String key : codonHash.keySet()) { - String key = (String) e.nextElement(); - Vector tmp = (Vector) codonHash.get(key); - - if (tmp.contains(codon)) + if (codonHash.get(key).contains(codon)) { return key; } diff --git a/src/jalview/structure/AtomSpec.java b/src/jalview/structure/AtomSpec.java new file mode 100644 index 0000000..d3e8d42 --- /dev/null +++ b/src/jalview/structure/AtomSpec.java @@ -0,0 +1,64 @@ +package jalview.structure; + +/** + * Java bean representing an atom in a PDB (or similar) structure model. + * + * @author gmcarstairs + * + */ +public class AtomSpec +{ + // TODO clarify do we want pdbFile here, or pdbId? + // compare highlightAtom in 2.8.2 for JalviewJmolBinding and + // javascript.MouseOverStructureListener + private String pdbFile; + + private String chain; + + private int pdbResNum; + + private int atomIndex; + + /** + * Constructor + * + * @param pdbFile + * @param chain + * @param resNo + * @param atomNo + */ + public AtomSpec(String pdbFile, String chain, int resNo, int atomNo) + { + this.pdbFile = pdbFile; + this.chain = chain; + this.pdbResNum = resNo; + this.atomIndex = atomNo; + } + + public String getPdbFile() + { + return pdbFile; + } + + public String getChain() + { + return chain; + } + + public int getPdbResNum() + { + return pdbResNum; + } + + public int getAtomIndex() + { + return atomIndex; + } + + @Override + public String toString() + { + return "pdbFile: " + pdbFile + ", chain: " + chain + ", res: " + + pdbResNum + ", atom: " + atomIndex; + } +} diff --git a/src/jalview/structure/CommandListener.java b/src/jalview/structure/CommandListener.java new file mode 100644 index 0000000..e5f3e36 --- /dev/null +++ b/src/jalview/structure/CommandListener.java @@ -0,0 +1,35 @@ +package jalview.structure; + +import jalview.commands.CommandI; + +/** + * Defines a listener for commands performed on another alignment. This is to + * support linked editing of two alternative representations of an alignment (in + * particular, cDNA and protein). + * + * @author gmcarstairs + * + */ +public interface CommandListener +{ + /** + * The listener may attempt to perform the specified command; the region acted + * on is determined by a callback to the StructureSelectionManager (which + * holds mappings between alignments). + * + * @param command + * @param undo + * @param ssm + * @param source + * the originator of the command + */ + public void mirrorCommand(CommandI command, boolean undo, + StructureSelectionManager ssm, VamsasSource source); + + /** + * Temporary workaround to make check for source == listener work. + * + * @return + */ + public VamsasSource getVamsasSource(); +} diff --git a/src/jalview/structure/SequenceListener.java b/src/jalview/structure/SequenceListener.java index 6f5ea50..cb65032 100644 --- a/src/jalview/structure/SequenceListener.java +++ b/src/jalview/structure/SequenceListener.java @@ -20,13 +20,19 @@ */ package jalview.structure; -import jalview.datamodel.*; +import jalview.datamodel.SequenceI; + public interface SequenceListener { + // TODO remove this? never called on SequenceListener type public void mouseOverSequence(SequenceI sequence, int index, int pos); public void highlightSequence(jalview.datamodel.SearchResults results); + // TODO remove this? never called public void updateColours(SequenceI sequence, int index); + + public VamsasSource getVamsasSource(); + } diff --git a/src/jalview/structure/StructureListener.java b/src/jalview/structure/StructureListener.java index 73576e9..69658bf 100644 --- a/src/jalview/structure/StructureListener.java +++ b/src/jalview/structure/StructureListener.java @@ -20,40 +20,27 @@ */ package jalview.structure; +import java.util.List; + public interface StructureListener { /** - * - * @return list of structure files (unique IDs/filenames) that this listener - * handles messages for, or null if generic listener (only used by - * removeListener method) + * Returns a list of structure files (unique IDs/filenames) that this listener + * handles messages for, or null if generic listener (only used by + * removeListener method) */ public String[] getPdbFile(); /** - * NOT A LISTENER METHOD! called by structure viewer when the given - * atom/structure has been moused over. Typically, implementors call - * StructureSelectionManager.mouseOverStructure - * - * @param atomIndex - * @param strInfo - */ - public void mouseOverStructure(int atomIndex, String strInfo); - - /** - * called by StructureSelectionManager to inform viewer to highlight given - * atomspec + * Called by StructureSelectionManager to inform viewer to highlight given + * atom positions * - * @param atomIndex - * @param pdbResNum - * @param chain - * @param pdbId + * @param atoms */ - public void highlightAtom(int atomIndex, int pdbResNum, String chain, - String pdbId); + public void highlightAtoms(List atoms); /** - * called by StructureSelectionManager when the colours of a sequence + * Called by StructureSelectionManager when the colours of a sequence * associated with a structure have changed. * * @param source @@ -62,19 +49,7 @@ public interface StructureListener public void updateColours(Object source); /** - * called by Jalview to get the colour for the given atomspec - * - * @param atomIndex - * @param pdbResNum - * @param chain - * @param pdbId - * @return - */ - public java.awt.Color getColour(int atomIndex, int pdbResNum, - String chain, String pdbId); - - /** - * called by structureSelectionManager to instruct implementor to release any + * Called by structureSelectionManager to instruct implementor to release any * direct references it may hold to the given object (typically, these are * Jalview alignment panels). * diff --git a/src/jalview/structure/StructureSelectionManager.java b/src/jalview/structure/StructureSelectionManager.java index 0434aac..ed5ee2d 100644 --- a/src/jalview/structure/StructureSelectionManager.java +++ b/src/jalview/structure/StructureSelectionManager.java @@ -22,19 +22,29 @@ package jalview.structure; import jalview.analysis.AlignSeq; import jalview.api.StructureSelectionManagerProvider; +import jalview.commands.CommandI; +import jalview.commands.EditCommand; +import jalview.commands.OrderCommand; import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; import jalview.datamodel.Annotation; import jalview.datamodel.PDBEntry; import jalview.datamodel.SearchResults; import jalview.datamodel.SequenceI; import jalview.io.AppletFormatAdapter; +import jalview.util.MappingUtils; import jalview.util.MessageManager; import java.io.PrintStream; +import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.IdentityHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.Vector; import MCview.Atom; @@ -44,10 +54,28 @@ public class StructureSelectionManager { static IdentityHashMap instances; - StructureMapping[] mappings; + private List mappings = new ArrayList(); - private boolean processSecondaryStructure = false, - secStructServices = false, addTempFacAnnot = false; + private boolean processSecondaryStructure = false; + + private boolean secStructServices = false; + + private boolean addTempFacAnnot = false; + + /* + * Set of any registered mappings between (dataset) sequences. + */ + Set seqmappings = new LinkedHashSet(); + + /* + * Reference counters for the above mappings. Remove mappings when ref count + * goes to zero. + */ + Map seqMappingRefCounts = new HashMap(); + + private List commandListeners = new ArrayList(); + + private List sel_listeners = new ArrayList(); /** * @return true if will try to use external services for processing secondary @@ -115,17 +143,18 @@ public class StructureSelectionManager */ public void reportMapping() { - if (mappings == null) + if (mappings.isEmpty()) { System.err.println("reportMapping: No PDB/Sequence mappings."); } else { - System.err.println("reportMapping: There are " + mappings.length + System.err.println("reportMapping: There are " + mappings.size() + " mappings."); - for (int m = 0; m < mappings.length; m++) + int i = 0; + for (StructureMapping sm : mappings) { - System.err.println("mapping " + m + " : " + mappings[m].pdbfile); + System.err.println("mapping " + i++ + " : " + sm.pdbfile); } } } @@ -246,16 +275,19 @@ public class StructureSelectionManager } } + /** + * Returns the file name for a mapped PDB id (or null if not mapped). + * + * @param pdbid + * @return + */ public String alreadyMappedToFile(String pdbid) { - if (mappings != null) + for (StructureMapping sm : mappings) { - for (int i = 0; i < mappings.length; i++) + if (sm.getPdbId().equals(pdbid)) { - if (mappings[i].getPdbId().equals(pdbid)) - { - return mappings[i].pdbfile; - } + return sm.pdbfile; } } return null; @@ -482,19 +514,7 @@ public class StructureSelectionManager mappingDetails.toString()); if (forStructureView) { - - if (mappings == null) - { - mappings = new StructureMapping[1]; - } - else - { - StructureMapping[] tmp = new StructureMapping[mappings.length + 1]; - System.arraycopy(mappings, 0, tmp, 0, mappings.length); - mappings = tmp; - } - - mappings[mappings.length - 1] = newMapping; + mappings.add(newMapping); } maxChain.transferResidueAnnotation(newMapping, sqmpping); } @@ -546,19 +566,18 @@ public class StructureSelectionManager } } - if (pdbs.size() > 0 && mappings != null) + if (pdbs.size() > 0) { - Vector tmp = new Vector(); - for (int i = 0; i < mappings.length; i++) + List tmp = new ArrayList(); + for (StructureMapping sm : mappings) { - if (!pdbs.contains(mappings[i].pdbfile)) + if (!pdbs.contains(sm.pdbfile)) { - tmp.addElement(mappings[i]); + tmp.add(sm); } } - mappings = new StructureMapping[tmp.size()]; - tmp.copyInto(mappings); + mappings = tmp; } } @@ -569,7 +588,6 @@ public class StructureSelectionManager // old or prematurely sent event return; } - boolean hasSequenceListeners = handlingVamsasMo || seqmappings != null; SearchResults results = null; SequenceI lastseq = null; int lastipos = -1, indexpos; @@ -581,33 +599,21 @@ public class StructureSelectionManager { results = new SearchResults(); } - if (mappings != null) + for (StructureMapping sm : mappings) { - for (int j = 0; j < mappings.length; j++) + if (sm.pdbfile.equals(pdbfile) && sm.pdbchain.equals(chain)) { - if (mappings[j].pdbfile.equals(pdbfile) - && mappings[j].pdbchain.equals(chain)) + indexpos = sm.getSeqPos(pdbResNum); + if (lastipos != indexpos && lastseq != sm.sequence) { - indexpos = mappings[j].getSeqPos(pdbResNum); - if (lastipos != indexpos && lastseq != mappings[j].sequence) + results.addResult(sm.sequence, indexpos, indexpos); + lastipos = indexpos; + lastseq = sm.sequence; + // construct highlighted sequence list + for (AlignedCodonFrame acf : seqmappings) { - results.addResult(mappings[j].sequence, indexpos, indexpos); - lastipos = indexpos; - lastseq = mappings[j].sequence; - // construct highlighted sequence list - if (seqmappings != null) - { - - Enumeration e = seqmappings.elements(); - while (e.hasMoreElements()) - - { - ((AlignedCodonFrame) e.nextElement()).markMappedRegion( - mappings[j].sequence, indexpos, results); - } - } + acf.markMappedRegion(sm.sequence, indexpos, results); } - } } } @@ -626,13 +632,11 @@ public class StructureSelectionManager } } - Vector seqmappings = null; // should be a simpler list of mapped seuqence - /** * highlight regions associated with a position (indexpos) in seq * * @param seq - * the sequeence that the mouse over occured on + * the sequence that the mouse over occurred on * @param indexpos * the absolute position being mouseovered in seq (0 to seq.length()) * @param index @@ -642,93 +646,54 @@ public class StructureSelectionManager public void mouseOverSequence(SequenceI seq, int indexpos, int index, VamsasSource source) { - boolean hasSequenceListeners = handlingVamsasMo || seqmappings != null; + boolean hasSequenceListeners = handlingVamsasMo + || !seqmappings.isEmpty(); SearchResults results = null; if (index == -1) { index = seq.findPosition(indexpos); } - StructureListener sl; - int atomNo = 0; for (int i = 0; i < listeners.size(); i++) { Object listener = listeners.elementAt(i); if (listener == source) { + // TODO listener (e.g. SeqPanel) is never == source (AlignViewport) + // Temporary fudge with SequenceListener.getVamsasSource() continue; } if (listener instanceof StructureListener) { - sl = (StructureListener) listener; - if (mappings == null) - { - continue; - } - for (int j = 0; j < mappings.length; j++) - { - if (mappings[j].sequence == seq - || mappings[j].sequence == seq.getDatasetSequence()) - { - atomNo = mappings[j].getAtomNum(index); - - if (atomNo > 0) - { - sl.highlightAtom(atomNo, mappings[j].getPDBResNum(index), - mappings[j].pdbchain, mappings[j].pdbfile); - } - } - } + highlightStructure((StructureListener) listener, seq, index); } else { - if (relaySeqMappings && hasSequenceListeners - && listener instanceof SequenceListener) + if (listener instanceof SequenceListener) { - // DEBUG - // System.err.println("relay Seq " + seq.getDisplayId(false) + " " + - // index); - - if (results == null) + final SequenceListener seqListener = (SequenceListener) listener; + if (hasSequenceListeners + && seqListener.getVamsasSource() != source) { - results = new SearchResults(); - if (index >= seq.getStart() && index <= seq.getEnd()) + if (relaySeqMappings) { - // construct highlighted sequence list - - if (seqmappings != null) + if (results == null) { - Enumeration e = seqmappings.elements(); - while (e.hasMoreElements()) - - { - ((AlignedCodonFrame) e.nextElement()).markMappedRegion( - seq, index, results); - } + results = MappingUtils.buildSearchResults(seq, index, + seqmappings); } - // hasSequenceListeners = results.getSize() > 0; if (handlingVamsasMo) { - // maybe have to resolve seq to a dataset seqeunce... - // add in additional direct sequence and/or dataset sequence - // highlighting results.addResult(seq, index, index); + } + seqListener.highlightSequence(results); } } - if (hasSequenceListeners) - { - ((SequenceListener) listener).highlightSequence(results); - } } else if (listener instanceof VamsasListener && !handlingVamsasMo) { - // DEBUG - // System.err.println("Vamsas from Seq " + seq.getDisplayId(false) + " - // " + - // index); - // pass the mouse over and absolute position onto the - // VamsasListener(s) - ((VamsasListener) listener).mouseOver(seq, indexpos, source); + ((VamsasListener) listener).mouseOverSequence(seq, indexpos, + source); } else if (listener instanceof SecondaryStructureListener) { @@ -740,6 +705,35 @@ public class StructureSelectionManager } /** + * Send suitable messages to a StructureListener to highlight atoms + * corresponding to the given sequence position. + * + * @param sl + * @param seq + * @param index + */ + protected void highlightStructure(StructureListener sl, SequenceI seq, + int index) + { + int atomNo; + List atoms = new ArrayList(); + for (StructureMapping sm : mappings) + { + if (sm.sequence == seq || sm.sequence == seq.getDatasetSequence()) + { + atomNo = sm.getAtomNum(index); + + if (atomNo > 0) + { + atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm + .getPDBResNum(index), atomNo)); + } + } + } + sl.highlightAtoms(atoms); + } + + /** * true if a mouse over event from an external (ie Vamsas) source is being * handled */ @@ -825,119 +819,114 @@ public class StructureSelectionManager public StructureMapping[] getMapping(String pdbfile) { - Vector tmp = new Vector(); - if (mappings != null) - { - for (int i = 0; i < mappings.length; i++) + List tmp = new ArrayList(); + for (StructureMapping sm : mappings) { - if (mappings[i].pdbfile.equals(pdbfile)) + if (sm.pdbfile.equals(pdbfile)) { - tmp.addElement(mappings[i]); + tmp.add(sm); } - } } - StructureMapping[] ret = new StructureMapping[tmp.size()]; - for (int i = 0; i < tmp.size(); i++) - { - ret[i] = (StructureMapping) tmp.elementAt(i); - } - - return ret; + return tmp.toArray(new StructureMapping[tmp.size()]); } public String printMapping(String pdbfile) { - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < mappings.length; i++) + StringBuilder sb = new StringBuilder(64); + for (StructureMapping sm : mappings) { - if (mappings[i].pdbfile.equals(pdbfile)) + if (sm.pdbfile.equals(pdbfile)) { - sb.append(mappings[i].mappingDetails); + sb.append(sm.mappingDetails); } } return sb.toString(); } - private int[] seqmappingrefs = null; // refcount for seqmappings elements - - private synchronized void modifySeqMappingList(boolean add, - AlignedCodonFrame[] codonFrames) + /** + * Decrement the reference counter for each of the given mappings, and remove + * it entirely if its reference counter reduces to zero. + * + * @param set + */ + public void removeMappings(Set set) { - if (!add && (seqmappings == null || seqmappings.size() == 0)) - { - return; - } - if (seqmappings == null) + if (set != null) { - seqmappings = new Vector(); + for (AlignedCodonFrame acf : set) + { + removeMapping(acf); + } } - if (codonFrames != null && codonFrames.length > 0) + } + + /** + * Decrement the reference counter for the given mapping, and remove it + * entirely if its reference counter reduces to zero. + * + * @param acf + */ + public void removeMapping(AlignedCodonFrame acf) + { + if (acf != null && seqmappings.contains(acf)) { - for (int cf = 0; cf < codonFrames.length; cf++) + int count = seqMappingRefCounts.get(acf); + count--; + if (count > 0) { - if (seqmappings.contains(codonFrames[cf])) - { - if (add) - { - seqmappingrefs[seqmappings.indexOf(codonFrames[cf])]++; - } - else - { - if (--seqmappingrefs[seqmappings.indexOf(codonFrames[cf])] <= 0) - { - int pos = seqmappings.indexOf(codonFrames[cf]); - int[] nr = new int[seqmappingrefs.length - 1]; - if (pos > 0) - { - System.arraycopy(seqmappingrefs, 0, nr, 0, pos); - } - if (pos < seqmappingrefs.length - 1) - { - System.arraycopy(seqmappingrefs, pos + 1, nr, 0, - seqmappingrefs.length - pos - 2); - } - } - } - } - else - { - if (add) - { - seqmappings.addElement(codonFrames[cf]); - - int[] nsr = new int[(seqmappingrefs == null) ? 1 - : seqmappingrefs.length + 1]; - if (seqmappingrefs != null && seqmappingrefs.length > 0) - { - System.arraycopy(seqmappingrefs, 0, nsr, 0, - seqmappingrefs.length); - } - nsr[(seqmappingrefs == null) ? 0 : seqmappingrefs.length] = 1; - seqmappingrefs = nsr; - } - } + seqMappingRefCounts.put(acf, count); + } + else + { + seqmappings.remove(acf); + seqMappingRefCounts.remove(acf); } } } - public void removeMappings(AlignedCodonFrame[] codonFrames) + /** + * Add each of the given codonFrames to the stored set. If not aready present, + * increments its reference count instead. + * + * @param set + */ + public void addMappings(Set set) { - modifySeqMappingList(false, codonFrames); + if (set != null) + { + for (AlignedCodonFrame acf : set) + { + addMapping(acf); + } + } } - public void addMappings(AlignedCodonFrame[] codonFrames) + /** + * Add the given mapping to the stored set, or if already stored, increment + * its reference counter. + */ + public void addMapping(AlignedCodonFrame acf) { - modifySeqMappingList(true, codonFrames); + if (acf != null) + { + if (seqmappings.contains(acf)) + { + seqMappingRefCounts.put(acf, seqMappingRefCounts.get(acf) + 1); + } + else + { + seqmappings.add(acf); + seqMappingRefCounts.put(acf, 1); + } + } } - Vector sel_listeners = new Vector(); - public void addSelectionListener(SelectionListener selecter) { if (!sel_listeners.contains(selecter)) { - sel_listeners.addElement(selecter); + sel_listeners.add(selecter); } } @@ -945,7 +934,7 @@ public class StructureSelectionManager { if (sel_listeners.contains(toremove)) { - sel_listeners.removeElement(toremove); + sel_listeners.remove(toremove); } } @@ -953,18 +942,11 @@ public class StructureSelectionManager jalview.datamodel.SequenceGroup selection, jalview.datamodel.ColumnSelection colsel, SelectionSource source) { - if (sel_listeners != null && sel_listeners.size() > 0) + for (SelectionListener slis : sel_listeners) { - Enumeration listeners = sel_listeners.elements(); - while (listeners.hasMoreElements()) + if (slis != source) { - SelectionListener slis = ((SelectionListener) listeners - .nextElement()); - if (slis != source) - { - slis.selection(selection, colsel, source); - } - ; + slis.selection(selection, colsel, source); } } } @@ -992,32 +974,6 @@ public class StructureSelectionManager } } - public void finalize() throws Throwable - { - if (listeners != null) - { - listeners.clear(); - listeners = null; - } - if (pdbIdFileName != null) - { - pdbIdFileName.clear(); - pdbIdFileName = null; - } - if (sel_listeners != null) - { - sel_listeners.clear(); - sel_listeners = null; - } - if (view_listeners != null) - { - view_listeners.clear(); - view_listeners = null; - } - mappings = null; - seqmappingrefs = null; - } - /** * release all references associated with this manager provider * @@ -1041,7 +997,6 @@ public class StructureSelectionManager } catch (Throwable x) { } - ; } } } @@ -1055,4 +1010,67 @@ public class StructureSelectionManager } } + public void addCommandListener(CommandListener cl) + { + if (!commandListeners.contains(cl)) + { + commandListeners.add(cl); + } + } + + public boolean hasCommandListener(CommandListener cl) + { + return this.commandListeners.contains(cl); + } + + public boolean removeCommandListener(CommandListener l) + { + return commandListeners.remove(l); + } + + /** + * Forward a command to any command listeners (except for the command's + * source). + * + * @param command + * the command to be broadcast (in its form after being performed) + * @param undo + * if true, the command was being 'undone' + * @param source + */ + public void commandPerformed(CommandI command, boolean undo, + VamsasSource source) + { + for (CommandListener listener : commandListeners) + { + listener.mirrorCommand(command, undo, this, source); + } + } + + /** + * Returns a new CommandI representing the given command as mapped to the + * given sequences. If no mapping could be made, or the command is not of a + * mappable kind, returns null. + * + * @param command + * @param undo + * @param mapTo + * @param gapChar + * @return + */ + public CommandI mapCommand(CommandI command, boolean undo, + final AlignmentI mapTo, char gapChar) + { + if (command instanceof EditCommand) + { + return MappingUtils.mapEditCommand((EditCommand) command, undo, + mapTo, gapChar, seqmappings); + } + else if (command instanceof OrderCommand) + { + return MappingUtils.mapOrderCommand((OrderCommand) command, undo, + mapTo, seqmappings); + } + return null; + } } diff --git a/src/jalview/structure/VamsasListener.java b/src/jalview/structure/VamsasListener.java index 8a390c4..c328c43 100644 --- a/src/jalview/structure/VamsasListener.java +++ b/src/jalview/structure/VamsasListener.java @@ -36,5 +36,6 @@ import jalview.datamodel.SequenceI; */ public interface VamsasListener { - public void mouseOver(SequenceI seq, int index, VamsasSource source); + public void mouseOverSequence(SequenceI seq, int index, + VamsasSource source); } diff --git a/src/jalview/structures/models/AAStructureBindingModel.java b/src/jalview/structures/models/AAStructureBindingModel.java index 664c903..653ec2d 100644 --- a/src/jalview/structures/models/AAStructureBindingModel.java +++ b/src/jalview/structures/models/AAStructureBindingModel.java @@ -3,15 +3,16 @@ package jalview.structures.models; import jalview.api.StructureSelectionManagerProvider; import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceI; +import jalview.structure.AtomSpec; import jalview.structure.StructureListener; import jalview.structure.StructureSelectionManager; import jalview.util.MessageManager; -import java.awt.event.ComponentEvent; import java.util.ArrayList; import java.util.List; /** + * * A base class to hold common function for protein structure model binding. * Initial version created by refactoring JMol and Chimera binding models, but * other structure viewers could in principle be accommodated in future. @@ -361,4 +362,21 @@ public abstract class AAStructureBindingModel extends } } + @Override + public void highlightAtoms(List atoms) + { + if (atoms != null) + { + for (AtomSpec atom : atoms) + { + highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(), + atom.getChain(), atom.getPdbFile()); + } + } + } + + // TODO Jmol and Chimera seem to expect pdbFile, javascript listener pdbId + protected abstract void highlightAtom(int atomIndex, int pdbResNum, + String chain, String pdbFile); + } \ No newline at end of file diff --git a/src/jalview/util/Comparison.java b/src/jalview/util/Comparison.java index 1934583..e224b71 100644 --- a/src/jalview/util/Comparison.java +++ b/src/jalview/util/Comparison.java @@ -20,18 +20,25 @@ */ package jalview.util; -import jalview.datamodel.*; +import jalview.datamodel.SequenceI; /** - * DOCUMENT ME! - * - * @author $author$ - * @version $Revision$ + * Assorted methods for analysing or comparing sequences. */ public class Comparison { - /** DOCUMENT ME!! */ - public static final String GapChars = " .-"; + private static final int EIGHTY_FIVE = 85; + + private static final int TO_UPPER_CASE = 'a' - 'A'; + + private static final char GAP_SPACE = ' '; + + private static final char GAP_DOT = '.'; + + private static final char GAP_DASH = '-'; + + public static final String GapChars = new String(new char[] + { GAP_SPACE, GAP_DOT, GAP_DASH }); /** * DOCUMENT ME! @@ -69,12 +76,12 @@ public class Comparison int ilen = si.length() - 1; int jlen = sj.length() - 1; - while (jalview.util.Comparison.isGap(si.charAt(start + ilen))) + while (Comparison.isGap(si.charAt(start + ilen))) { ilen--; } - while (jalview.util.Comparison.isGap(sj.charAt(start + jlen))) + while (Comparison.isGap(sj.charAt(start + jlen))) { jlen--; } @@ -225,47 +232,60 @@ public class Comparison } /** - * DOCUMENT ME! + * Answers true if the supplied character is a recognised gap character, else + * false. Currently hard-coded to recognise '-', '-' or ' ' (hyphen / dot / + * space). * * @param c - * DOCUMENT ME! * - * @return DOCUMENT ME! + * @return */ public static final boolean isGap(char c) { - return (c == '-' || c == '.' || c == ' ') ? true : false; + return (c == GAP_DASH || c == GAP_DOT || c == GAP_SPACE) ? true : false; } + /** + * Answers true if more than 85% of the sequence residues (ignoring gaps) are + * A, G, C, T or U, else false. This is just a heuristic guess and may give a + * wrong answer (as AGCT are also animo acid codes). + * + * @param seqs + * @return + */ public static final boolean isNucleotide(SequenceI[] seqs) { - int i = 0, iSize = seqs.length, j, jSize; - float nt = 0, aa = 0; - char c; - while (i < iSize) + if (seqs == null) + { + return false; + } + int ntCount = 0; + int aaCount = 0; + for (SequenceI seq : seqs) { - jSize = seqs[i].getLength(); - for (j = 0; j < jSize; j++) + for (char c : seq.getSequence()) { - c = seqs[i].getCharAt(j); if ('a' <= c && c <= 'z') { - c -= ('a' - 'A'); + c -= TO_UPPER_CASE; } if (c == 'A' || c == 'G' || c == 'C' || c == 'T' || c == 'U') { - nt++; + ntCount++; } - else if (!jalview.util.Comparison.isGap(seqs[i].getCharAt(j))) + else if (!Comparison.isGap(c)) { - aa++; + aaCount++; } } - i++; } - if ((nt / (nt + aa)) > 0.85f) + /* + * Check for nucleotide count > 85% of total count (in a form that evades + * int / float conversion or divide by zero). + */ + if (ntCount * 100 > EIGHTY_FIVE * (ntCount + aaCount)) { return true; } diff --git a/src/jalview/util/DBRefUtils.java b/src/jalview/util/DBRefUtils.java index 9a4ffc8..8163f05 100755 --- a/src/jalview/util/DBRefUtils.java +++ b/src/jalview/util/DBRefUtils.java @@ -20,9 +20,15 @@ */ package jalview.util; -import java.util.*; +import jalview.datamodel.DBRefEntry; +import jalview.datamodel.PDBEntry; +import jalview.datamodel.SequenceI; -import jalview.datamodel.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; +import java.util.Vector; public class DBRefUtils { @@ -48,8 +54,8 @@ public class DBRefUtils { return dbrefs; } - Hashtable srcs = new Hashtable(); - Vector res = new Vector(); + Map srcs = new HashMap(); + ArrayList res = new ArrayList(); for (int i = 0; i < sources.length; i++) { @@ -59,18 +65,14 @@ public class DBRefUtils { if (srcs.containsKey(dbrefs[i].getSource())) { - res.addElement(dbrefs[i]); + res.add(dbrefs[i]); } } if (res.size() > 0) { DBRefEntry[] reply = new DBRefEntry[res.size()]; - for (int i = 0; i < res.size(); i++) - { - reply[i] = (DBRefEntry) res.elementAt(i); - } - return reply; + return res.toArray(reply); } res = null; // there are probable memory leaks in the hashtable! @@ -169,7 +171,9 @@ public class DBRefUtils DbRefComp comparator) { if (ref == null || entry == null) + { return null; + } Vector rfs = new Vector(); for (int i = 0; i < ref.length; i++) { @@ -303,6 +307,7 @@ public class DBRefUtils { if ((refa.getMap() == null && refb.getMap() == null) || (refa.getMap() != null && refb.getMap() != null)) + { if ((refb.getMap().getMap() == null && refa.getMap().getMap() == null) || (refb.getMap().getMap() != null && refa.getMap().getMap() != null && refb @@ -311,6 +316,7 @@ public class DBRefUtils { return true; } + } } } return false; diff --git a/src/jalview/util/Format.java b/src/jalview/util/Format.java index 98500da..d14e4ad 100755 --- a/src/jalview/util/Format.java +++ b/src/jalview/util/Format.java @@ -54,6 +54,8 @@ public class Format private char fmt; // one of cdeEfgGiosxXos + private final String formatString; + /** * Creates a new Format object. * @@ -62,6 +64,7 @@ public class Format */ public Format(String s) { + formatString = s; width = 0; precision = -1; pre = ""; @@ -622,7 +625,7 @@ public class Format /** * Formats a character into a string (like sprintf in C) * - * @param x + * @param debounceTrap * the value to format * @return the formatted string */ @@ -641,7 +644,7 @@ public class Format /** * Formats a string into a larger string (like sprintf in C) * - * @param x + * @param debounceTrap * the value to format * @return the formatted string */ @@ -938,4 +941,10 @@ public class Format return f + p.substring(p.length() - 3, p.length()); } + + @Override + public String toString() + { + return formatString; + } } diff --git a/src/jalview/util/MapList.java b/src/jalview/util/MapList.java index c566c84..2641659 100644 --- a/src/jalview/util/MapList.java +++ b/src/jalview/util/MapList.java @@ -20,86 +20,121 @@ */ package jalview.util; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** - * MapList Simple way of bijectively mapping a non-contiguous linear range to - * another non-contiguous linear range Use at your own risk! TODO: efficient - * implementation of private posMap method TODO: test/ensure that sense of from - * and to ratio start position is conserved (codon start position recovery) - * TODO: optimize to use int[][] arrays rather than vectors. + * A simple way of bijectively mapping a non-contiguous linear range to another + * non-contiguous linear range. + * + * Use at your own risk! + * + * TODO: efficient implementation of private posMap method + * + * TODO: test/ensure that sense of from and to ratio start position is conserved + * (codon start position recovery) */ public class MapList { + /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) + * Subregions (base 1) described as { [start1, end1], [start2, end2], ...} + */ + private List fromShifts = new ArrayList(); + + /* + * Same format as fromShifts, for the 'mapped to' sequence + */ + private List toShifts = new ArrayList(); + + /* + * number of steps in fromShifts to one toRatio unit + */ + private int fromRatio; + + /* + * number of steps in toShifts to one fromRatio + */ + private int toRatio; + + /* + * lowest and highest value in the from Map + */ + private int fromLowest; + + private int fromHighest; + + /* + * lowest and highest value in the to Map + */ + private int toLowest; + + private int toHighest; + + /** + * Two MapList objects are equal if they are the same object, or they both + * have populated shift ranges and all values are the same. */ - public boolean equals(MapList obj) + @Override + public boolean equals(Object o) { + // TODO should also override hashCode to ensure equal objects have equal + // hashcodes + if (o == null || !(o instanceof MapList)) + { + return false; + } + + MapList obj = (MapList) o; if (obj == this) - return true; - if (obj != null && obj.fromRatio == fromRatio && obj.toRatio == toRatio - && obj.fromShifts != null && obj.toShifts != null) { - int i, iSize = fromShifts.size(), j, jSize = obj.fromShifts.size(); - if (iSize != jSize) - return false; - for (i = 0, iSize = fromShifts.size(), j = 0, jSize = obj.fromShifts - .size(); i < iSize;) - { - int[] mi = (int[]) fromShifts.elementAt(i++); - int[] mj = (int[]) obj.fromShifts.elementAt(j++); - if (mi[0] != mj[0] || mi[1] != mj[1]) - return false; - } - iSize = toShifts.size(); - jSize = obj.toShifts.size(); - if (iSize != jSize) - return false; - for (i = 0, j = 0; i < iSize;) - { - int[] mi = (int[]) toShifts.elementAt(i++); - int[] mj = (int[]) obj.toShifts.elementAt(j++); - if (mi[0] != mj[0] || mi[1] != mj[1]) - return false; - } return true; } - return false; + if (obj.fromRatio != fromRatio || obj.toRatio != toRatio + || obj.fromShifts == null || obj.toShifts == null) + { + return false; + } + return Arrays + .deepEquals(fromShifts.toArray(), obj.fromShifts.toArray()) + && Arrays + .deepEquals(toShifts.toArray(), obj.toShifts.toArray()); } - public Vector fromShifts; - - public Vector toShifts; - - int fromRatio; // number of steps in fromShifts to one toRatio unit - - int toRatio; // number of steps in toShifts to one fromRatio - /** + * Returns the 'from' ranges as {[start1, end1], [start2, end2], ...} * - * @return series of intervals mapped in from + * @return */ - public int[] getFromRanges() + public List getFromRanges() { - return getRanges(fromShifts); + return fromShifts; } - public int[] getToRanges() + /** + * Returns the 'to' ranges as {[start1, end1], [start2, end2], ...} + * + * @return + */ + public List getToRanges() { - return getRanges(toShifts); + return toShifts; } - private int[] getRanges(Vector shifts) + /** + * Flattens a list of [start, end] into a single [start1, end1, start2, + * end2,...] array. + * + * @param shifts + * @return + */ + protected static int[] getRanges(List shifts) { int[] rnges = new int[2 * shifts.size()]; - Enumeration e = shifts.elements(); int i = 0; - while (e.hasMoreElements()) + for (int[] r : shifts) { - int r[] = (int[]) e.nextElement(); rnges[i++] = r[0]; rnges[i++] = r[1]; } @@ -107,16 +142,6 @@ public class MapList } /** - * lowest and highest value in the from Map - */ - int[] fromRange = null; - - /** - * lowest and highest value in the to Map - */ - int[] toRange = null; - - /** * * @return length of mapped phrase in from */ @@ -136,100 +161,136 @@ public class MapList public int getFromLowest() { - return fromRange[0]; + return fromLowest; } public int getFromHighest() { - return fromRange[1]; + return fromHighest; } public int getToLowest() { - return toRange[0]; + return toLowest; } public int getToHighest() { - return toRange[1]; - } - - private void ensureRange(int[] limits, int pos) - { - if (limits[0] > pos) - limits[0] = pos; - if (limits[1] < pos) - limits[1] = pos; + return toHighest; } + /** + * Constructor. + * + * @param from + * contiguous regions as [start1, end1, start2, end2, ...] + * @param to + * same format as 'from' + * @param fromRatio + * phrase length in 'from' (e.g. 3 for dna) + * @param toRatio + * phrase length in 'to' (e.g. 1 for protein) + */ public MapList(int from[], int to[], int fromRatio, int toRatio) { - fromRange = new int[] - { from[0], from[1] }; - toRange = new int[] - { to[0], to[1] }; - - fromShifts = new Vector(); + this.fromRatio = fromRatio; + this.toRatio = toRatio; + fromLowest = from[0]; + fromHighest = from[1]; for (int i = 0; i < from.length; i += 2) { - ensureRange(fromRange, from[i]); - ensureRange(fromRange, from[i + 1]); + fromLowest = Math.min(fromLowest, from[i]); + fromHighest = Math.max(fromHighest, from[i + 1]); - fromShifts.addElement(new int[] + fromShifts.add(new int[] { from[i], from[i + 1] }); } - toShifts = new Vector(); + + toLowest = to[0]; + toHighest = to[1]; for (int i = 0; i < to.length; i += 2) { - ensureRange(toRange, to[i]); - ensureRange(toRange, to[i + 1]); - toShifts.addElement(new int[] + toLowest = Math.min(toLowest, to[i]); + toHighest = Math.max(toHighest, to[i + 1]); + toShifts.add(new int[] { to[i], to[i + 1] }); } - this.fromRatio = fromRatio; - this.toRatio = toRatio; } + /** + * Copy constructor. Creates an identical mapping. + * + * @param map + */ public MapList(MapList map) { - this.fromRange = new int[] - { map.fromRange[0], map.fromRange[1] }; - this.toRange = new int[] - { map.toRange[0], map.toRange[1] }; + // TODO not used - remove? + this.fromLowest = map.fromLowest; + this.fromHighest = map.fromHighest; + this.toLowest = map.toLowest; + this.toHighest = map.toHighest; + this.fromRatio = map.fromRatio; this.toRatio = map.toRatio; if (map.fromShifts != null) { - this.fromShifts = new Vector(); - Enumeration e = map.fromShifts.elements(); - while (e.hasMoreElements()) + for (int[] r : map.fromShifts) { - int[] el = (int[]) e.nextElement(); - fromShifts.addElement(new int[] - { el[0], el[1] }); + fromShifts.add(new int[] + { r[0], r[1] }); } } if (map.toShifts != null) { - this.toShifts = new Vector(); - Enumeration e = map.toShifts.elements(); - while (e.hasMoreElements()) + for (int[] r : map.toShifts) { - int[] el = (int[]) e.nextElement(); - toShifts.addElement(new int[] - { el[0], el[1] }); + toShifts.add(new int[] + { r[0], r[1] }); } } } /** + * Constructor given ranges as lists of [start, end] positions + * + * @param fromRange + * @param toRange + * @param fromRatio + * @param toRatio + */ + public MapList(List fromRange, List toRange, + int fromRatio, int toRatio) + { + this.fromShifts = fromRange; + this.toShifts = toRange; + this.fromRatio = fromRatio; + this.toRatio = toRatio; + + fromLowest = Integer.MAX_VALUE; + fromHighest = 0; + for (int[] range : fromRange) { + fromLowest = Math.min(fromLowest, range[0]); + fromHighest = Math.max(fromHighest, range[1]); + } + + toLowest = Integer.MAX_VALUE; + toHighest = 0; + for (int[] range : toRange) + { + toLowest = Math.min(toLowest, range[0]); + toHighest = Math.max(toHighest, range[1]); + } + } + + /** * get all mapped positions from 'from' to 'to' * * @return int[][] { int[] { fromStart, fromFinish, toStart, toFinish }, int * [fromFinish-fromStart+2] { toStart..toFinish mappings}} */ - public int[][] makeFromMap() + protected int[][] makeFromMap() { + // TODO not used - remove?? return posMap(fromShifts, fromRatio, toShifts, toRatio); } @@ -238,27 +299,30 @@ public class MapList * * @return int[to position]=position mapped in from */ - public int[][] makeToMap() + protected int[][] makeToMap() { + // TODO not used - remove?? return posMap(toShifts, toRatio, fromShifts, fromRatio); } /** * construct an int map for intervals in intVals * - * @param intVals + * @param shiftTo * @return int[] { from, to pos in range }, int[range.to-range.from+1] * returning mapped position */ - private int[][] posMap(Vector intVals, int ratio, Vector toIntVals, + private int[][] posMap(List shiftTo, int ratio, + List shiftFrom, int toRatio) { - int iv = 0, ivSize = intVals.size(); + // TODO not used - remove?? + int iv = 0, ivSize = shiftTo.size(); if (iv >= ivSize) { return null; } - int[] intv = (int[]) intVals.elementAt(iv++); + int[] intv = shiftTo.get(iv++); int from = intv[0], to = intv[1]; if (from > to) { @@ -267,7 +331,7 @@ public class MapList } while (iv < ivSize) { - intv = (int[]) intVals.elementAt(iv++); + intv = shiftTo.get(iv++); if (intv[0] < from) { from = intv[0]; @@ -289,7 +353,7 @@ public class MapList int mp[][] = new int[to - from + 2][]; for (int i = 0; i < mp.length; i++) { - int[] m = shift(i + from, intVals, ratio, toIntVals, toRatio); + int[] m = shift(i + from, shiftTo, ratio, shiftFrom, toRatio); if (m != null) { if (i == 0) @@ -345,6 +409,7 @@ public class MapList * shifts.insertElementAt(new int[] { pos, shift}, sidx); else * rshift[1]+=shift; } */ + /** * shift from pos to To(pos) * @@ -373,23 +438,24 @@ public class MapList /** * - * @param fromShifts + * @param shiftTo * @param fromRatio - * @param toShifts + * @param shiftFrom * @param toRatio * @return */ - private int[] shift(int pos, Vector fromShifts, int fromRatio, - Vector toShifts, int toRatio) + protected static int[] shift(int pos, List shiftTo, int fromRatio, + List shiftFrom, int toRatio) { - int[] fromCount = countPos(fromShifts, pos); + // TODO: javadoc; tests + int[] fromCount = countPos(shiftTo, pos); if (fromCount == null) { return null; } int fromRemainder = (fromCount[0] - 1) % fromRatio; int toCount = 1 + (((fromCount[0] - 1) / fromRatio) * toRatio); - int[] toPos = countToPos(toShifts, toCount); + int[] toPos = countToPos(shiftFrom, toCount); if (toPos == null) { return null; // throw new Error("Bad Mapping!"); @@ -402,16 +468,16 @@ public class MapList /** * count how many positions pos is along the series of intervals. * - * @param intVals + * @param shiftTo * @param pos * @return number of positions or null if pos is not within intervals */ - private int[] countPos(Vector intVals, int pos) + protected static int[] countPos(List shiftTo, int pos) { - int count = 0, intv[], iv = 0, ivSize = intVals.size(); + int count = 0, intv[], iv = 0, ivSize = shiftTo.size(); while (iv < ivSize) { - intv = (int[]) intVals.elementAt(iv++); + intv = shiftTo.get(iv++); if (intv[0] <= intv[1]) { if (pos >= intv[0] && pos <= intv[1]) @@ -443,17 +509,18 @@ public class MapList /** * count out pos positions into a series of intervals and return the position * - * @param intVals + * @param shiftFrom * @param pos * @return position pos in interval set */ - private int[] countToPos(Vector intVals, int pos) + protected static int[] countToPos(List shiftFrom, int pos) { - int count = 0, diff = 0, iv = 0, ivSize = intVals.size(), intv[] = + int count = 0, diff = 0, iv = 0, ivSize = shiftFrom.size(); + int[] intv = { 0, 0 }; while (iv < ivSize) { - intv = (int[]) intVals.elementAt(iv++); + intv = shiftFrom.get(iv++); diff = intv[1] - intv[0]; if (diff >= 0) { @@ -487,69 +554,68 @@ public class MapList * find series of intervals mapping from start-end in the From map. * * @param start - * position in to map + * position mapped 'to' * @param end - * position in to map - * @return series of ranges in from map + * position mapped 'to' + * @return series of [start, end] ranges in sequence mapped 'from' */ public int[] locateInFrom(int start, int end) { // inefficient implementation int fromStart[] = shiftTo(start); - int fromEnd[] = shiftTo(end); // needs to be inclusive of end of symbol - // position - if (fromStart == null || fromEnd == null) - return null; - int iv[] = getIntervals(fromShifts, fromStart, fromEnd, fromRatio); - return iv; + // needs to be inclusive of end of symbol position + int fromEnd[] = shiftTo(end); + + return getIntervals(fromShifts, fromStart, fromEnd, fromRatio); } /** * find series of intervals mapping from start-end in the to map. * * @param start - * position in from map + * position mapped 'from' * @param end - * position in from map - * @return series of ranges in to map + * position mapped 'from' + * @return series of [start, end] ranges in sequence mapped 'to' */ public int[] locateInTo(int start, int end) { - // inefficient implementation int toStart[] = shiftFrom(start); int toEnd[] = shiftFrom(end); - if (toStart == null || toEnd == null) - return null; - int iv[] = getIntervals(toShifts, toStart, toEnd, toRatio); - return iv; + return getIntervals(toShifts, toStart, toEnd, toRatio); } /** * like shift - except returns the intervals in the given vector of shifts * which were spanned in traversing fromStart to fromEnd * - * @param fromShifts2 + * @param shiftFrom * @param fromStart * @param fromEnd * @param fromRatio2 * @return series of from,to intervals from from first position of starting * region to final position of ending region inclusive */ - private int[] getIntervals(Vector fromShifts2, int[] fromStart, + protected static int[] getIntervals(List shiftFrom, + int[] fromStart, int[] fromEnd, int fromRatio2) { + if (fromStart == null || fromEnd == null) + { + return null; + } int startpos, endpos; startpos = fromStart[0]; // first position in fromStart endpos = fromEnd[0]; // last position in fromEnd int endindx = (fromRatio2 - 1); // additional positions to get to last // position from endpos - int intv = 0, intvSize = fromShifts2.size(); + int intv = 0, intvSize = shiftFrom.size(); int iv[], i = 0, fs = -1, fe_s = -1, fe = -1; // containing intervals // search intervals to locate ones containing startpos and count endindx // positions on from endpos while (intv < intvSize && (fs == -1 || fe == -1)) { - iv = (int[]) fromShifts2.elementAt(intv++); + iv = shiftFrom.get(intv++); if (fe_s > -1) { endpos = iv[0]; // start counting from beginning of interval @@ -612,39 +678,45 @@ public class MapList i++; } if (fs == fe && fe == -1) + { return null; - Vector ranges = new Vector(); + } + List ranges = new ArrayList(); if (fs <= fe) { intv = fs; i = fs; // truncate initial interval - iv = (int[]) fromShifts2.elementAt(intv++); + iv = shiftFrom.get(intv++); iv = new int[] { iv[0], iv[1] };// clone if (i == fs) + { iv[0] = startpos; + } while (i != fe) { - ranges.addElement(iv); // add initial range - iv = (int[]) fromShifts2.elementAt(intv++); // get next interval + ranges.add(iv); // add initial range + iv = shiftFrom.get(intv++); // get next interval iv = new int[] { iv[0], iv[1] };// clone i++; } if (i == fe) + { iv[1] = endpos; - ranges.addElement(iv); // add only - or final range + } + ranges.add(iv); // add only - or final range } else { // walk from end of interval. - i = fromShifts2.size() - 1; + i = shiftFrom.size() - 1; while (i > fs) { i--; } - iv = (int[]) fromShifts2.elementAt(i); + iv = shiftFrom.get(i); iv = new int[] { iv[1], iv[0] };// reverse and clone // truncate initial interval @@ -654,8 +726,8 @@ public class MapList } while (--i != fe) { // fix apparent logic bug when fe==-1 - ranges.addElement(iv); // add (truncated) reversed interval - iv = (int[]) fromShifts2.elementAt(i); + ranges.add(iv); // add (truncated) reversed interval + iv = shiftFrom.get(i); iv = new int[] { iv[1], iv[0] }; // reverse and clone } @@ -664,7 +736,7 @@ public class MapList // interval is already reversed iv[1] = endpos; } - ranges.addElement(iv); // add only - or final range + ranges.add(iv); // add only - or final range } // create array of start end intervals. int[] range = null; @@ -676,10 +748,10 @@ public class MapList i = 0; while (intv < intvSize) { - iv = (int[]) ranges.elementAt(intv); + iv = ranges.get(intv); range[i++] = iv[0]; range[i++] = iv[1]; - ranges.setElementAt(null, intv++); // remove + ranges.set(intv++, null); // remove } } return range; @@ -694,6 +766,7 @@ public class MapList */ public int getToPosition(int mpos) { + // TODO not used - remove?? int[] mp = shiftTo(mpos); if (mp != null) { @@ -730,6 +803,7 @@ public class MapList */ public int getMappedPosition(int pos) { + // TODO not used - remove?? int[] mp = shiftFrom(pos); if (mp != null) { @@ -740,6 +814,7 @@ public class MapList public int[] getMappedWord(int pos) { + // TODO not used - remove?? int[] mp = shiftFrom(pos); if (mp != null) { @@ -750,223 +825,6 @@ public class MapList } /** - * test routine. not incremental. - * - * @param ml - * @param fromS - * @param fromE - */ - public static void testMap(MapList ml, int fromS, int fromE) - { - for (int from = 1; from <= 25; from++) - { - int[] too = ml.shiftFrom(from); - System.out.print("ShiftFrom(" + from + ")=="); - if (too == null) - { - System.out.print("NaN\n"); - } - else - { - System.out.print(too[0] + " % " + too[1] + " (" + too[2] + ")"); - System.out.print("\t+--+\t"); - int[] toofrom = ml.shiftTo(too[0]); - if (toofrom != null) - { - if (toofrom[0] != from) - { - System.err.println("Mapping not reflexive:" + from + " " - + too[0] + "->" + toofrom[0]); - } - System.out.println("ShiftTo(" + too[0] + ")==" + toofrom[0] - + " % " + toofrom[1] + " (" + toofrom[2] + ")"); - } - else - { - System.out.println("ShiftTo(" + too[0] + ")==" - + "NaN! - not Bijective Mapping!"); - } - } - } - int mmap[][] = ml.makeFromMap(); - System.out.println("FromMap : (" + mmap[0][0] + " " + mmap[0][1] + " " - + mmap[0][2] + " " + mmap[0][3] + " "); - for (int i = 1; i <= mmap[1].length; i++) - { - if (mmap[1][i - 1] == -1) - { - System.out.print(i + "=XXX"); - - } - else - { - System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1])); - } - if (i % 20 == 0) - { - System.out.print("\n"); - } - else - { - System.out.print(","); - } - } - // test range function - System.out.print("\nTest locateInFrom\n"); - { - int f = mmap[0][2], t = mmap[0][3]; - while (f <= t) - { - System.out.println("Range " + f + " to " + t); - int rng[] = ml.locateInFrom(f, t); - if (rng != null) - { - for (int i = 0; i < rng.length; i++) - { - System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); - } - } - else - { - System.out.println("No range!"); - } - System.out.print("\nReversed\n"); - rng = ml.locateInFrom(t, f); - if (rng != null) - { - for (int i = 0; i < rng.length; i++) - { - System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); - } - } - else - { - System.out.println("No range!"); - } - System.out.print("\n"); - f++; - t--; - } - } - System.out.print("\n"); - mmap = ml.makeToMap(); - System.out.println("ToMap : (" + mmap[0][0] + " " + mmap[0][1] + " " - + mmap[0][2] + " " + mmap[0][3] + " "); - for (int i = 1; i <= mmap[1].length; i++) - { - if (mmap[1][i - 1] == -1) - { - System.out.print(i + "=XXX"); - - } - else - { - System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1])); - } - if (i % 20 == 0) - { - System.out.print("\n"); - } - else - { - System.out.print(","); - } - } - System.out.print("\n"); - // test range function - System.out.print("\nTest locateInTo\n"); - { - int f = mmap[0][2], t = mmap[0][3]; - while (f <= t) - { - System.out.println("Range " + f + " to " + t); - int rng[] = ml.locateInTo(f, t); - if (rng != null) - { - for (int i = 0; i < rng.length; i++) - { - System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); - } - } - else - { - System.out.println("No range!"); - } - System.out.print("\nReversed\n"); - rng = ml.locateInTo(t, f); - if (rng != null) - { - for (int i = 0; i < rng.length; i++) - { - System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); - } - } - else - { - System.out.println("No range!"); - } - f++; - t--; - System.out.print("\n"); - } - } - - } - - public static void main(String argv[]) - { - MapList ml = new MapList(new int[] - { 1, 5, 10, 15, 25, 20 }, new int[] - { 51, 1 }, 1, 3); - MapList ml1 = new MapList(new int[] - { 1, 3, 17, 4 }, new int[] - { 51, 1 }, 1, 3); - MapList ml2 = new MapList(new int[] - { 1, 60 }, new int[] - { 1, 20 }, 3, 1); - // test internal consistency - int to[] = new int[51]; - MapList.testMap(ml, 1, 60); - MapList mldna = new MapList(new int[] - { 2, 2, 6, 8, 12, 16 }, new int[] - { 1, 3 }, 3, 1); - int[] frm = mldna.locateInFrom(1, 1); - testLocateFrom(mldna, 1, 1, new int[] - { 2, 2, 6, 7 }); - MapList.testMap(mldna, 1, 3); - /* - * for (int from=1; from<=51; from++) { int[] too=ml.shiftTo(from); int[] - * toofrom=ml.shiftFrom(too[0]); - * System.out.println("ShiftFrom("+from+")=="+too[0]+" % - * "+too[1]+"\t+-+\tShiftTo("+too[0]+")=="+toofrom[0]+" % "+toofrom[1]); } - */ - System.out.print("Success?\n"); // if we get here - something must be - // working! - } - - private static void testLocateFrom(MapList mldna, int i, int j, int[] ks) - { - int[] frm = mldna.locateInFrom(i, j); - if (frm == ks || java.util.Arrays.equals(frm, ks)) - { - System.out.println("Success test locate from " + i + " to " + j); - } - else - { - System.err.println("Failed test locate from " + i + " to " + j); - for (int c = 0; c < frm.length; c++) - { - System.err.print(frm[c] + ((c % 2 == 0) ? "," : ";")); - } - System.err.println("Expected"); - for (int c = 0; c < ks.length; c++) - { - System.err.print(ks[c] + ((c % 2 == 0) ? "," : ";")); - } - } - } - - /** * * @return a MapList whose From range is this maplist's To Range, and vice * versa @@ -987,6 +845,7 @@ public class MapList */ public boolean containsEither(boolean local, MapList map) { + // TODO not used - remove? if (local) { return ((getFromLowest() >= map.getFromLowest() && getFromHighest() <= map diff --git a/src/jalview/util/MappingUtils.java b/src/jalview/util/MappingUtils.java new file mode 100644 index 0000000..4cfb49e --- /dev/null +++ b/src/jalview/util/MappingUtils.java @@ -0,0 +1,545 @@ +package jalview.util; + +import jalview.analysis.AlignmentSorter; +import jalview.api.AlignViewportI; +import jalview.commands.CommandI; +import jalview.commands.EditCommand; +import jalview.commands.EditCommand.Action; +import jalview.commands.EditCommand.Edit; +import jalview.commands.OrderCommand; +import jalview.datamodel.AlignedCodonFrame; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.AlignmentOrder; +import jalview.datamodel.ColumnSelection; +import jalview.datamodel.SearchResults; +import jalview.datamodel.SearchResults.Match; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Helper methods for manipulations involving sequence mappings. + * + * @author gmcarstairs + * + */ +public final class MappingUtils +{ + + /** + * Helper method to map a CUT or PASTE command. + * + * @param edit + * the original command + * @param undo + * if true, the command is to be undone + * @param targetSeqs + * the mapped sequences to apply the mapped command to + * @param result + * the mapped EditCommand to add to + * @param mappings + */ + protected static void mapCutOrPaste(Edit edit, boolean undo, + List targetSeqs, EditCommand result, + Set mappings) + { + Action action = edit.getAction(); + if (undo) + { + action = action.getUndoAction(); + } + // TODO write this + System.err.println("MappingUtils.mapCutOrPaste not yet implemented"); + } + + /** + * Returns a new EditCommand representing the given command as mapped to the + * given sequences. If there is no mapping, returns null. + * + * @param command + * @param undo + * @param mapTo + * @param gapChar + * @param mappings + * @return + */ + public static EditCommand mapEditCommand(EditCommand command, + boolean undo, final AlignmentI mapTo, char gapChar, + Set mappings) + { + /* + * For now, only support mapping from protein edits to cDna + */ + if (!mapTo.isNucleotide()) + { + return null; + } + + /* + * Cache a copy of the target sequences so we can mimic successive edits on + * them. This lets us compute mappings for all edits in the set. + */ + Map targetCopies = new HashMap(); + for (SequenceI seq : mapTo.getSequences()) + { + SequenceI ds = seq.getDatasetSequence(); + if (ds != null) + { + final SequenceI copy = new Sequence(seq); + copy.setDatasetSequence(ds); + targetCopies.put(ds, copy); + } + } + + /* + * Compute 'source' sequences as they were before applying edits: + */ + Map originalSequences = command.priorState(undo); + + EditCommand result = new EditCommand(); + Iterator edits = command.getEditIterator(!undo); + while (edits.hasNext()) + { + Edit edit = edits.next(); + if (edit.getAction() == Action.CUT + || edit.getAction() == Action.PASTE) + { + mapCutOrPaste(edit, undo, mapTo.getSequences(), result, mappings); + } + else if (edit.getAction() == Action.INSERT_GAP + || edit.getAction() == Action.DELETE_GAP) + { + mapInsertOrDelete(edit, undo, originalSequences, + mapTo.getSequences(), targetCopies, gapChar, result, + mappings); + } + } + return result.getSize() > 0 ? result : null; + } + + /** + * Helper method to map an edit command to insert or delete gaps. + * + * @param edit + * the original command + * @param undo + * if true, the action is to undo the command + * @param originalSequences + * the sequences the command acted on + * @param targetSeqs + * @param targetCopies + * @param gapChar + * @param result + * the new EditCommand to add mapped commands to + * @param mappings + */ + protected static void mapInsertOrDelete(Edit edit, boolean undo, + Map originalSequences, + final List targetSeqs, + Map targetCopies, char gapChar, + EditCommand result, Set mappings) + { + Action action = edit.getAction(); + + /* + * Invert sense of action if an Undo. + */ + if (undo) + { + action = action.getUndoAction(); + } + final int count = edit.getNumber(); + final int editPos = edit.getPosition(); + for (SequenceI seq : edit.getSequences()) + { + /* + * Get residue position at (or to right of) edit location. Note we use our + * 'copy' of the sequence before editing for this. + */ + SequenceI ds = seq.getDatasetSequence(); + if (ds == null) + { + continue; + } + final SequenceI actedOn = originalSequences.get(ds); + final int seqpos = actedOn.findPosition(editPos); + + /* + * Determine all mappings from this position to mapped sequences. + */ + SearchResults sr = buildSearchResults(seq, seqpos, mappings); + + if (!sr.isEmpty()) + { + for (SequenceI targetSeq : targetSeqs) + { + ds = targetSeq.getDatasetSequence(); + if (ds == null) + { + continue; + } + SequenceI copyTarget = targetCopies.get(ds); + final int[] match = sr.getResults(copyTarget, 0, + copyTarget.getLength()); + if (match != null) + { + final int ratio = 3; // TODO: compute this - how? + final int mappedCount = count * ratio; + + /* + * Shift Delete start position left, as it acts on positions to its + * right. + */ + int mappedEditPos = action == Action.DELETE_GAP ? match[0] + - mappedCount : match[0]; + Edit e = result.new Edit(action, new SequenceI[] + { targetSeq }, mappedEditPos, mappedCount, gapChar); + result.addEdit(e); + + /* + * and 'apply' the edit to our copy of its target sequence + */ + if (action == Action.INSERT_GAP) + { + copyTarget.setSequence(new String(StringUtils.insertCharAt( + copyTarget.getSequence(), mappedEditPos, mappedCount, + gapChar))); + } + else if (action == Action.DELETE_GAP) + { + copyTarget.setSequence(new String(StringUtils.deleteChars( + copyTarget.getSequence(), mappedEditPos, + mappedEditPos + mappedCount))); + } + } + } + } + /* + * and 'apply' the edit to our copy of its source sequence + */ + if (action == Action.INSERT_GAP) + { + actedOn.setSequence(new String(StringUtils.insertCharAt( + actedOn.getSequence(), editPos, count, gapChar))); + } + else if (action == Action.DELETE_GAP) + { + actedOn.setSequence(new String(StringUtils.deleteChars( + actedOn.getSequence(), editPos, editPos + count))); + } + } + } + + /** + * Returns a SearchResults object describing the mapped region corresponding + * to the specified sequence position. + * + * @param seq + * @param index + * @param seqmappings + * @return + */ + public static SearchResults buildSearchResults(SequenceI seq, int index, + Set seqmappings) + { + SearchResults results; + results = new SearchResults(); + if (index >= seq.getStart() && index <= seq.getEnd()) + { + for (AlignedCodonFrame acf : seqmappings) + { + acf.markMappedRegion(seq, index, results); + } + } + return results; + } + + /** + * Returns a (possibly empty) SequenceGroup containing any sequences in the + * mapped viewport corresponding to the given group in the source viewport. + * + * @param sg + * @param mapFrom + * @param mapTo + * @return + */ + public static SequenceGroup mapSequenceGroup(SequenceGroup sg, + AlignViewportI mapFrom, AlignViewportI mapTo) + { + /* + * Note the SequenceGroup holds aligned sequences, the mappings hold dataset + * sequences. + */ + boolean targetIsNucleotide = mapTo.isNucleotide(); + AlignViewportI protein = targetIsNucleotide ? mapFrom : mapTo; + Set codonFrames = protein.getAlignment() + .getCodonFrames(); + + /* + * Copy group name, name colours, but not sequences or sequence colour + * scheme + */ + SequenceGroup mappedGroup = new SequenceGroup(sg); + mappedGroup.cs = mapTo.getGlobalColourScheme(); + mappedGroup.clear(); + // TODO set width of mapped group + + for (SequenceI selected : sg.getSequences()) + { + for (AlignedCodonFrame acf : codonFrames) + { + SequenceI mappedSequence = targetIsNucleotide ? acf + .getDnaForAaSeq(selected) : acf.getAaForDnaSeq(selected); + if (mappedSequence != null) + { + for (SequenceI seq : mapTo.getAlignment().getSequences()) + { + if (seq.getDatasetSequence() == mappedSequence) + { + mappedGroup.addSequence(seq, false); + break; + } + } + } + } + } + return mappedGroup; + } + + /** + * Returns an OrderCommand equivalent to the given one, but acting on mapped + * sequences as described by the mappings, or null if no mapping can be made. + * + * @param command + * the original order command + * @param undo + * if true, the action is to undo the sort + * @param mapTo + * the alignment we are mapping to + * @param mappings + * the mappings available + * @return + */ + public static CommandI mapOrderCommand(OrderCommand command, + boolean undo, AlignmentI mapTo, Set mappings) + { + SequenceI[] sortOrder = command.getSequenceOrder(undo); + List mappedOrder = new ArrayList(); + int j = 0; + for (SequenceI seq : sortOrder) + { + for (AlignedCodonFrame acf : mappings) + { + /* + * Try protein-to-Dna, failing that try dna-to-protein + */ + SequenceI mappedSeq = acf.getDnaForAaSeq(seq); + if (mappedSeq == null) + { + mappedSeq = acf.getAaForDnaSeq(seq); + } + if (mappedSeq != null) + { + for (SequenceI seq2 : mapTo.getSequences()) + { + if (seq2.getDatasetSequence() == mappedSeq) + { + mappedOrder.add(seq2); + j++; + break; + } + } + } + } + } + + /* + * Return null if no mappings made. + */ + if (j == 0) + { + return null; + } + + /* + * Add any unmapped sequences on the end of the sort in their original + * ordering. + */ + if (j < mapTo.getHeight()) + { + for (SequenceI seq : mapTo.getSequences()) + { + if (!mappedOrder.contains(seq)) + { + mappedOrder.add(seq); + } + } + } + + /* + * Have to sort the sequences before constructing the OrderCommand - which + * then resorts them?!? + */ + final SequenceI[] mappedOrderArray = mappedOrder + .toArray(new SequenceI[mappedOrder.size()]); + SequenceI[] oldOrder = mapTo.getSequencesArray(); + AlignmentSorter.sortBy(mapTo, new AlignmentOrder(mappedOrderArray)); + final OrderCommand result = new OrderCommand(command.getDescription(), + oldOrder, mapTo); + return result; + } + + /** + * Returns a ColumnSelection in the 'mapTo' view which corresponds to the + * given selection in the 'mapFrom' view. We assume one is nucleotide, the + * other is protein (and holds the mappings from codons to protein residues). + * + * @param colsel + * @param mapFrom + * @param mapTo + * @return + */ + public static ColumnSelection mapColumnSelection(ColumnSelection colsel, + AlignViewportI mapFrom, AlignViewportI mapTo) + { + boolean targetIsNucleotide = mapTo.isNucleotide(); + AlignViewportI protein = targetIsNucleotide ? mapFrom : mapTo; + Set codonFrames = protein.getAlignment() + .getCodonFrames(); + ColumnSelection mappedColumns = new ColumnSelection(); + char fromGapChar = mapFrom.getAlignment().getGapCharacter(); + + // FIXME allow for hidden columns + + /* + * For each mapped column, find the range of columns that residues in that + * column map to. + */ + for (Object obj : colsel.getSelected()) + { + int col = ((Integer) obj).intValue(); + int mappedToMin = Integer.MAX_VALUE; + int mappedToMax = Integer.MIN_VALUE; + + /* + * For each sequence in the 'from' alignment + */ + for (SequenceI fromSeq : mapFrom.getAlignment().getSequences()) + { + /* + * Ignore gaps (unmapped anyway) + */ + if (fromSeq.getCharAt(col) == fromGapChar) + { + continue; + } + + /* + * Get the residue position and find the mapped position. + */ + int residuePos = fromSeq.findPosition(col); + SearchResults sr = buildSearchResults(fromSeq, residuePos, + codonFrames); + for (Match m : sr.getResults()) + { + int mappedStartResidue = m.getStart(); + int mappedEndResidue = m.getEnd(); + SequenceI mappedSeq = m.getSequence(); + + /* + * Locate the aligned sequence whose dataset is mappedSeq. TODO a + * datamodel that can do this efficiently. + */ + for (SequenceI toSeq : mapTo.getAlignment().getSequences()) + { + if (toSeq.getDatasetSequence() == mappedSeq) + { + int mappedStartCol = toSeq.findIndex(mappedStartResidue); + int mappedEndCol = toSeq.findIndex(mappedEndResidue); + mappedToMin = Math.min(mappedToMin, mappedStartCol); + mappedToMax = Math.max(mappedToMax, mappedEndCol); + // System.out.println(fromSeq.getName() + " mapped to cols " + // + mappedStartCol + ":" + mappedEndCol); + break; + // note: remove break if we ever want to map one to many sequences + } + } + } + } + /* + * Add the range of mapped columns to the mapped selection (converting + * base 1 to base 0). Note that this may include intron-only regions which + * lie between the start and end ranges of the selection. + */ + for (int i = mappedToMin; i <= mappedToMax; i++) + { + mappedColumns.addElement(i - 1); + } + } + return mappedColumns; + } + + /** + * Returns the mapped codon for a given aligned sequence column position (base + * 0). + * + * @param seq + * an aligned peptide sequence + * @param col + * an aligned column position (base 0) + * @param mappings + * a set of codon mappings + * @return the bases of the mapped codon in the cDNA dataset sequence, or null + * if not found + */ + public static char[] findCodonFor(SequenceI seq, int col, + Set mappings) + { + int dsPos = seq.findPosition(col); + for (AlignedCodonFrame mapping : mappings) + { + if (mapping.involvesSequence(seq)) + { + return mapping.getMappedCodon(seq.getDatasetSequence(), dsPos); + } + } + return null; + } + + /** + * Converts a series of [start, end] ranges into an array of individual + * positions. + * + * @param ranges + * @return + */ + public static int[] flattenRanges(int[] ranges) + { + /* + * Count how many positions altogether + */ + int count = 0; + for (int i = 0; i < ranges.length - 1; i += 2) + { + count += ranges[i + 1] - ranges[i] + 1; + } + + int[] result = new int[count]; + int k = 0; + for (int i = 0; i < ranges.length - 1; i += 2) + { + for (int j = ranges[i]; j <= ranges[i + 1]; j++) + { + result[k++] = j; + } + } + return result; + } +} diff --git a/src/jalview/util/MessageManager.java b/src/jalview/util/MessageManager.java index a92b29a..4001cb2 100644 --- a/src/jalview/util/MessageManager.java +++ b/src/jalview/util/MessageManager.java @@ -92,6 +92,11 @@ public class MessageManager public static String formatMessage(String key, Object... params) { + return MessageFormat.format(rb.getString(key), params); + } + + public static String formatMessage(String key, String[] params) + { return MessageFormat.format(rb.getString(key), (Object[]) params); } diff --git a/src/jalview/util/ParseHtmlBodyAndLinks.java b/src/jalview/util/ParseHtmlBodyAndLinks.java index 19726b9..7aec22d 100644 --- a/src/jalview/util/ParseHtmlBodyAndLinks.java +++ b/src/jalview/util/ParseHtmlBodyAndLinks.java @@ -32,6 +32,8 @@ import java.util.regex.Pattern; */ public class ParseHtmlBodyAndLinks { + private static final Pattern LEFT_ANGLE_BRACKET_PATTERN = Pattern.compile("<"); + String orig = null; public String getOrig() @@ -153,7 +155,7 @@ public class ParseHtmlBodyAndLinks { // instead of parsing the html into plaintext // clean the description ready for embedding in html - sb = new StringBuffer(Pattern.compile("<").matcher(description) + sb = new StringBuffer(LEFT_ANGLE_BRACKET_PATTERN.matcher(description) .replaceAll("<")); } diff --git a/src/jalview/util/QuickSort.java b/src/jalview/util/QuickSort.java index c630d96..4826bc3 100755 --- a/src/jalview/util/QuickSort.java +++ b/src/jalview/util/QuickSort.java @@ -20,29 +20,103 @@ */ package jalview.util; +import java.util.Arrays; +import java.util.Comparator; + +/** + * A class to perform efficient sorting of arrays of objects based on arrays of + * scores or other attributes. For example, residues by percentage frequency. + * + * @author gmcarstairs + * + */ public class QuickSort { + static class FloatComparator implements Comparator + { + + private final float[] values; + + FloatComparator(float[] v) + { + values = v; + } + + @Override + public int compare(Integer o1, Integer o2) + { + return Float.compare(values[o1], values[o2]); + } + + } + + static class IntComparator implements Comparator + { + + private final int[] values; + + IntComparator(int[] v) + { + values = v; + } + + @Override + public int compare(Integer o1, Integer o2) + { + return Integer.compare(values[o1], values[o2]); + } + + } + + /** + * Sorts both arrays with respect to ascending order of the items in the first + * array. + * + * @param arr + * @param s + */ public static void sort(int[] arr, Object[] s) { sort(arr, 0, arr.length - 1, s); } + /** + * Sorts both arrays with respect to ascending order of the items in the first + * array. + * + * @param arr + * @param s + */ public static void sort(float[] arr, Object[] s) { sort(arr, 0, arr.length - 1, s); } + /** + * Sorts both arrays with respect to ascending order of the items in the first + * array. + * + * @param arr + * @param s + */ public static void sort(double[] arr, Object[] s) { sort(arr, 0, arr.length - 1, s); } + /** + * Sorts both arrays with respect to descending order of the items in the + * first array. + * + * @param arr + * @param s + */ public static void sort(String[] arr, Object[] s) { stringSort(arr, 0, arr.length - 1, s); } - public static void stringSort(String[] arr, int p, int r, Object[] s) + static void stringSort(String[] arr, int p, int r, Object[] s) { int q; @@ -54,7 +128,7 @@ public class QuickSort } } - public static void sort(float[] arr, int p, int r, Object[] s) + static void sort(float[] arr, int p, int r, Object[] s) { int q; @@ -66,7 +140,7 @@ public class QuickSort } } - public static void sort(double[] arr, int p, int r, Object[] s) + static void sort(double[] arr, int p, int r, Object[] s) { int q; @@ -78,7 +152,7 @@ public class QuickSort } } - public static void sort(int[] arr, int p, int r, Object[] s) + static void sort(int[] arr, int p, int r, Object[] s) { int q; @@ -90,7 +164,7 @@ public class QuickSort } } - private static int partition(float[] arr, int p, int r, Object[] s) + static int partition(float[] arr, int p, int r, Object[] s) { float x = arr[p]; int i = p - 1; @@ -125,7 +199,42 @@ public class QuickSort } } - private static int partition(int[] arr, int p, int r, Object[] s) + static int partition(float[] arr, int p, int r, char[] s) + { + float x = arr[p]; + int i = p - 1; + int j = r + 1; + + while (true) + { + do + { + j = j - 1; + } while (arr[j] > x); + + do + { + i = i + 1; + } while (arr[i] < x); + + if (i < j) + { + float tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + + char tmp2 = s[i]; + s[i] = s[j]; + s[j] = tmp2; + } + else + { + return j; + } + } + } + + static int partition(int[] arr, int p, int r, Object[] s) { int x = arr[p]; int i = p - 1; @@ -160,7 +269,7 @@ public class QuickSort } } - private static int partition(double[] arr, int p, int r, Object[] s) + static int partition(double[] arr, int p, int r, Object[] s) { double x = arr[p]; int i = p - 1; @@ -195,7 +304,7 @@ public class QuickSort } } - private static int stringPartition(String[] arr, int p, int r, Object[] s) + static int stringPartition(String[] arr, int p, int r, Object[] s) { String x = arr[p]; int i = p - 1; @@ -229,4 +338,218 @@ public class QuickSort } } } + + /** + * Sorts both arrays to give ascending order in the first array, by first + * partitioning into zero and non-zero values before sorting the latter. + * + * @param arr + * @param s + */ + public static void sort(float[] arr, char[] s) + { + /* + * Sort all zero values to the front + */ + float[] f1 = new float[arr.length]; + char[] s1 = new char[s.length]; + int nextZeroValue = 0; + int nextNonZeroValue = arr.length - 1; + for (int i = 0; i < arr.length; i++) + { + float val = arr[i]; + if (val > 0f) + { + f1[nextNonZeroValue] = val; + s1[nextNonZeroValue] = s[i]; + nextNonZeroValue--; + } + else + { + f1[nextZeroValue] = val; + s1[nextZeroValue] = s[i]; + nextZeroValue++; + } + } + + /* + * Copy zero values back to original arrays + */ + System.arraycopy(f1, 0, arr, 0, nextZeroValue); + System.arraycopy(s1, 0, s, 0, nextZeroValue); + + if (nextZeroValue == arr.length) + { + return; // all zero + } + /* + * Sort the non-zero values + */ + float[] nonZeroFloats = Arrays + .copyOfRange(f1, nextZeroValue, f1.length); + char[] nonZeroChars = Arrays.copyOfRange(s1, nextZeroValue, s1.length); + externalSort(nonZeroFloats, nonZeroChars); + // sort(nonZeroFloats, 0, nonZeroFloats.length - 1, nonZeroChars); + + /* + * Assemble sorted non-zero results + */ + System.arraycopy(nonZeroFloats, 0, arr, nextZeroValue, + nonZeroFloats.length); + System.arraycopy(nonZeroChars, 0, s, nextZeroValue, nonZeroChars.length); + } + + /** + * Sort by making an array of indices, and sorting it using a comparator that + * refers to the float values. + * + * @see http + * ://stackoverflow.com/questions/4859261/get-the-indices-of-an-array- + * after-sorting + * @param arr + * @param s + */ + protected static void externalSort(float[] arr, char[] s) + { + final int length = arr.length; + Integer[] indices = makeIndexArray(length); + Arrays.sort(indices, new FloatComparator(arr)); + + /* + * Copy the array values as per the sorted indices + */ + float[] sortedFloats = new float[length]; + char[] sortedChars = new char[s.length]; + for (int i = 0; i < length; i++) + { + sortedFloats[i] = arr[indices[i]]; + sortedChars[i] = s[indices[i]]; + } + + /* + * And copy the sorted values back into the arrays + */ + System.arraycopy(sortedFloats, 0, arr, 0, length); + System.arraycopy(sortedChars, 0, s, 0, s.length); + } + + /** + * Make an array whose values are 0...length. + * + * @param length + * @return + */ + protected static Integer[] makeIndexArray(final int length) + { + Integer[] indices = new Integer[length]; + for (int i = 0; i < length; i++) + { + indices[i] = i; + } + return indices; + } + + static void sort(float[] arr, int p, int r, char[] s) + { + int q; + if (p < r) + { + q = partition(arr, p, r, s); + sort(arr, p, q, s); + sort(arr, q + 1, r, s); + } + } + + /** + * Sorts both arrays to give ascending order in the first array, by first + * partitioning into zero and non-zero values before sorting the latter. + * + * @param arr + * @param s + */ + public static void sort(int[] arr, char[] s) + { + /* + * Sort all zero values to the front + */ + int[] f1 = new int[arr.length]; + char[] s1 = new char[s.length]; + int nextZeroValue = 0; + int nextNonZeroValue = arr.length - 1; + for (int i = 0; i < arr.length; i++) + { + int val = arr[i]; + if (val > 0f) + { + f1[nextNonZeroValue] = val; + s1[nextNonZeroValue] = s[i]; + nextNonZeroValue--; + } + else + { + f1[nextZeroValue] = val; + s1[nextZeroValue] = s[i]; + nextZeroValue++; + } + } + + /* + * Copy zero values back to original arrays + */ + System.arraycopy(f1, 0, arr, 0, nextZeroValue); + System.arraycopy(s1, 0, s, 0, nextZeroValue); + + if (nextZeroValue == arr.length) + { + return; // all zero + } + /* + * Sort the non-zero values + */ + int[] nonZeroInts = Arrays + .copyOfRange(f1, nextZeroValue, f1.length); + char[] nonZeroChars = Arrays.copyOfRange(s1, nextZeroValue, s1.length); + externalSort(nonZeroInts, nonZeroChars); + // sort(nonZeroFloats, 0, nonZeroFloats.length - 1, nonZeroChars); + + /* + * Assemble sorted non-zero results + */ + System.arraycopy(nonZeroInts, 0, arr, nextZeroValue, nonZeroInts.length); + System.arraycopy(nonZeroChars, 0, s, nextZeroValue, nonZeroChars.length); + } + + /** + * Sort by making an array of indices, and sorting it using a comparator that + * refers to the float values. + * + * @see http + * ://stackoverflow.com/questions/4859261/get-the-indices-of-an-array- + * after-sorting + * @param arr + * @param s + */ + protected static void externalSort(int[] arr, char[] s) + { + final int length = arr.length; + Integer[] indices = makeIndexArray(length); + Arrays.sort(indices, new IntComparator(arr)); + + /* + * Copy the array values as per the sorted indices + */ + int[] sortedInts = new int[length]; + char[] sortedChars = new char[s.length]; + for (int i = 0; i < length; i++) + { + sortedInts[i] = arr[indices[i]]; + sortedChars[i] = s[indices[i]]; + } + + /* + * And copy the sorted values back into the arrays + */ + System.arraycopy(sortedInts, 0, arr, 0, length); + System.arraycopy(sortedChars, 0, s, 0, s.length); + } } diff --git a/src/jalview/util/ReverseListIterator.java b/src/jalview/util/ReverseListIterator.java new file mode 100644 index 0000000..69a7345 --- /dev/null +++ b/src/jalview/util/ReverseListIterator.java @@ -0,0 +1,42 @@ +package jalview.util; + +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +/** + * An iterator that traverses a list backwards. + * + * @author gmcarstairs (and checked against + * org.codehaus.groovey.runtime.ReverseListIterator) + * + * @param + */ +public class ReverseListIterator implements Iterator +{ + + private ListIterator iterator; + + public ReverseListIterator(List stuff) + { + this.iterator = stuff.listIterator(stuff.size()); + } + @Override + public boolean hasNext() + { + return iterator.hasPrevious(); + } + + @Override + public E next() + { + return iterator.previous(); + } + + @Override + public void remove() + { + iterator.remove(); + } + +} diff --git a/src/jalview/util/ShiftList.java b/src/jalview/util/ShiftList.java index 6d3ce1f..38d6a32 100644 --- a/src/jalview/util/ShiftList.java +++ b/src/jalview/util/ShiftList.java @@ -20,7 +20,8 @@ */ package jalview.util; -import java.util.*; +import java.util.ArrayList; +import java.util.List; /** * ShiftList Simple way of mapping a linear series to a new linear range with @@ -29,11 +30,11 @@ import java.util.*; */ public class ShiftList { - public Vector shifts; + private List shifts; public ShiftList() { - shifts = new Vector(); + shifts = new ArrayList(); } /** @@ -46,21 +47,23 @@ public class ShiftList */ public void addShift(int pos, int shift) { - int sidx = 0; - int[] rshift = null; - while (sidx < shifts.size() - && (rshift = (int[]) shifts.elementAt(sidx))[0] < pos) - { - sidx++; - } - if (sidx == shifts.size()) + synchronized (shifts) { - shifts.insertElementAt(new int[] - { pos, shift }, sidx); - } - else - { - rshift[1] += shift; + int sidx = 0; + int[] rshift = null; + while (sidx < shifts.size() && (rshift = shifts.get(sidx))[0] < pos) + { + sidx++; + } + if (sidx == shifts.size()) + { + shifts.add(sidx, new int[] + { pos, shift }); + } + else + { + rshift[1] += shift; + } } } @@ -81,7 +84,7 @@ public class ShiftList int sidx = 0; int rshift[]; while (sidx < shifts.size() - && (rshift = ((int[]) shifts.elementAt(sidx++)))[0] <= pos) + && (rshift = (shifts.get(sidx++)))[0] <= pos) { shifted += rshift[1]; } @@ -91,9 +94,9 @@ public class ShiftList /** * clear all shifts */ - public void clear() + public synchronized void clear() { - shifts.removeAllElements(); + shifts.clear(); } /** @@ -104,15 +107,17 @@ public class ShiftList public ShiftList getInverse() { ShiftList inverse = new ShiftList(); - if (shifts != null) + synchronized (shifts) { - for (int i = 0, j = shifts.size(); i < j; i++) + if (shifts != null) { - int[] sh = (int[]) shifts.elementAt(i); - if (sh != null) + for (int[] sh : shifts) { - inverse.shifts.addElement(new int[] - { sh[0], -sh[1] }); + if (sh != null) + { + inverse.shifts.add(new int[] + { sh[0], -sh[1] }); + } } } } @@ -120,8 +125,8 @@ public class ShiftList } /** - * parse a 1d map of position 1 getShifts() + { + return shifts; + } } diff --git a/src/jalview/util/StringUtils.java b/src/jalview/util/StringUtils.java new file mode 100644 index 0000000..1325ce5 --- /dev/null +++ b/src/jalview/util/StringUtils.java @@ -0,0 +1,233 @@ +package jalview.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + + +public class StringUtils +{ + private static final Pattern DELIMITERS_PATTERN = Pattern.compile(".*='[^']*(?!')"); + + private static final boolean DEBUG = false; + + /** + * Returns a new character array, after inserting characters into the given + * character array. + * + * @param in + * the character array to insert into + * @param position + * the 0-based position for insertion + * @param count + * the number of characters to insert + * @param ch + * the character to insert + */ + public static final char[] insertCharAt(char[] in, int position, + int count, + char ch) + { + char[] tmp = new char[in.length + count]; + + if (position >= in.length) + { + System.arraycopy(in, 0, tmp, 0, in.length); + position = in.length; + } + else + { + System.arraycopy(in, 0, tmp, 0, position); + } + + int index = position; + while (count > 0) + { + tmp[index++] = ch; + count--; + } + + if (position < in.length) + { + System.arraycopy(in, position, tmp, index, + in.length - position); + } + + return tmp; + } + + /** + * Delete + * + * @param in + * @param from + * @param to + * @return + */ + public static final char[] deleteChars(char[] in, int from, int to) + { + if (from >= in.length) + { + return in; + } + + char[] tmp; + + if (to >= in.length) + { + tmp = new char[from]; + System.arraycopy(in, 0, tmp, 0, from); + to = in.length; + } + else + { + tmp = new char[in.length - to + from]; + System.arraycopy(in, 0, tmp, 0, from); + System.arraycopy(in, to, tmp, from, in.length - to); + } + return tmp; + } + + /** + * Returns the last part of 'input' after the last occurrence of 'token'. For + * example to extract only the filename from a full path or URL. + * + * @param input + * @param token + * a delimiter which must be in regular expression format + * @return + */ + public static String getLastToken(String input, String token) + { + if (input == null) + { + return null; + } + if (token == null) + { + return input; + } + String[] st = input.split(token); + return st[st.length - 1]; + } + + /** + * Parses the input string into components separated by the delimiter. Unlike + * String.split(), this method will ignore occurrences of the delimiter which + * are nested within single quotes in name-value pair values, e.g. a='b,c'. + * + * @param input + * @param delimiter + * @return elements separated by separator + */ + public static String[] separatorListToArray(String input, String delimiter) + { + int seplen = delimiter.length(); + if (input == null || input.equals("") || input.equals(delimiter)) + { + return null; + } + List jv = new ArrayList(); + int cp = 0, pos, escape; + boolean wasescaped = false, wasquoted = false; + String lstitem = null; + while ((pos = input.indexOf(delimiter, cp)) >= cp) + { + escape = (pos > 0 && input.charAt(pos - 1) == '\\') ? -1 : 0; + if (wasescaped || wasquoted) + { + // append to previous pos + jv.set(jv.size() - 1, + lstitem = lstitem + delimiter + + input.substring(cp, pos + escape)); + } + else + { + jv.add(lstitem = input.substring(cp, pos + escape)); + } + cp = pos + seplen; + wasescaped = escape == -1; + // last separator may be in an unmatched quote + wasquoted = DELIMITERS_PATTERN.matcher(lstitem).matches(); + } + if (cp < input.length()) + { + String c = input.substring(cp); + if (wasescaped || wasquoted) + { + // append final separator + jv.set(jv.size() - 1, lstitem + delimiter + c); + } + else + { + if (!c.equals(delimiter)) + { + jv.add(c); + } + } + } + if (jv.size() > 0) + { + String[] v = jv.toArray(new String[jv.size()]); + jv.clear(); + if (DEBUG) + { + System.err.println("Array from '" + delimiter + + "' separated List:\n" + v.length); + for (int i = 0; i < v.length; i++) + { + System.err.println("item " + i + " '" + v[i] + "'"); + } + } + return v; + } + if (DEBUG) + { + System.err.println("Empty Array from '" + delimiter + + "' separated List"); + } + return null; + } + + /** + * Returns a string which contains the list elements delimited by the + * separator. Null items are ignored. If the input is null or has length zero, + * a single delimiter is returned. + * + * @param list + * @param separator + * @return concatenated string + */ + public static String arrayToSeparatorList(String[] list, String separator) + { + StringBuffer v = new StringBuffer(); + if (list != null && list.length > 0) + { + for (int i = 0, iSize = list.length; i < iSize; i++) + { + if (list[i] != null) + { + if (v.length() > 0) + { + v.append(separator); + } + // TODO - escape any separator values in list[i] + v.append(list[i]); + } + } + if (DEBUG) + { + System.err.println("Returning '" + separator + + "' separated List:\n"); + System.err.println(v); + } + return v.toString(); + } + if (DEBUG) + { + System.err.println("Returning empty '" + separator + + "' separated List\n"); + } + return "" + separator; + } +} diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index 6cec30a..7054ed3 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -20,15 +20,31 @@ */ package jalview.viewmodel; +import java.awt.Color; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.Deque; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; import jalview.analysis.Conservation; import jalview.api.AlignCalcManagerI; import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; import jalview.api.FeaturesDisplayedI; +import jalview.api.ViewStyleI; +import jalview.commands.CommandI; +import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.AlignmentView; import jalview.datamodel.Annotation; +import jalview.datamodel.CigarArray; import jalview.datamodel.ColumnSelection; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceCollectionI; @@ -38,18 +54,15 @@ import jalview.schemes.Blosum62ColourScheme; import jalview.schemes.ColourSchemeI; import jalview.schemes.PIDColourScheme; import jalview.schemes.ResidueProperties; +import jalview.structure.CommandListener; +import jalview.structure.StructureSelectionManager; +import jalview.structure.VamsasSource; +import jalview.viewmodel.styles.ViewStyle; import jalview.workers.AlignCalcManager; +import jalview.workers.ComplementConsensusThread; import jalview.workers.ConsensusThread; import jalview.workers.StrucConsensusThread; -import java.awt.Color; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; -import java.util.Vector; - /** * base class holding visualization and analysis attributes and common logic for * an active alignment view displayed in the GUI @@ -57,152 +70,496 @@ import java.util.Vector; * @author jimp * */ -public abstract class AlignmentViewport implements AlignViewportI +public abstract class AlignmentViewport implements AlignViewportI, + ViewStyleI, CommandListener, VamsasSource { + protected ViewStyleI viewStyle = new ViewStyle(); + /** - * alignment displayed in the viewport. Please use get/setter + * A viewport that hosts the cDna view of this (protein), or vice versa (if + * set). */ - protected AlignmentI alignment; + AlignViewportI codingComplement = null; - protected String sequenceSetID; + FeaturesDisplayedI featuresDisplayed = null; + + protected Deque historyList = new ArrayDeque(); + + protected Deque redoList = new ArrayDeque(); /** - * probably unused indicator that view is of a dataset rather than an - * alignment + * @param name + * @see jalview.api.ViewStyleI#setFontName(java.lang.String) */ - protected boolean isDataset = false; + public void setFontName(String name) + { + viewStyle.setFontName(name); + } - private Map hiddenRepSequences; + /** + * @param style + * @see jalview.api.ViewStyleI#setFontStyle(int) + */ + public void setFontStyle(int style) + { + viewStyle.setFontStyle(style); + } - protected ColumnSelection colSel = new ColumnSelection(); + /** + * @param size + * @see jalview.api.ViewStyleI#setFontSize(int) + */ + public void setFontSize(int size) + { + viewStyle.setFontSize(size); + } - public boolean autoCalculateConsensus = true; + /** + * @return + * @see jalview.api.ViewStyleI#getFontStyle() + */ + public int getFontStyle() + { + return viewStyle.getFontStyle(); + } - protected boolean autoCalculateStrucConsensus = true; + /** + * @return + * @see jalview.api.ViewStyleI#getFontName() + */ + public String getFontName() + { + return viewStyle.getFontName(); + } - protected boolean ignoreGapsInConsensusCalculation = false; + /** + * @return + * @see jalview.api.ViewStyleI#getFontSize() + */ + public int getFontSize() + { + return viewStyle.getFontSize(); + } - protected ColourSchemeI globalColourScheme = null; + /** + * @param upperCasebold + * @see jalview.api.ViewStyleI#setUpperCasebold(boolean) + */ + public void setUpperCasebold(boolean upperCasebold) + { + viewStyle.setUpperCasebold(upperCasebold); + } /** - * gui state - changes to colour scheme propagated to all groups + * @return + * @see jalview.api.ViewStyleI#isUpperCasebold() */ - private boolean colourAppliesToAllGroups; + public boolean isUpperCasebold() + { + return viewStyle.isUpperCasebold(); + } /** - * @param value - * indicating if subsequent colourscheme changes will be propagated - * to all groups + * @return + * @see jalview.api.ViewStyleI#isSeqNameItalics() + */ + public boolean isSeqNameItalics() + { + return viewStyle.isSeqNameItalics(); + } + + /** + * @param colourByReferenceSeq + * @see jalview.api.ViewStyleI#setColourByReferenceSeq(boolean) + */ + public void setColourByReferenceSeq(boolean colourByReferenceSeq) + { + viewStyle.setColourByReferenceSeq(colourByReferenceSeq); + } + + /** + * @param b + * @see jalview.api.ViewStyleI#setColourAppliesToAllGroups(boolean) */ public void setColourAppliesToAllGroups(boolean b) { - colourAppliesToAllGroups = b; + viewStyle.setColourAppliesToAllGroups(b); } /** - * - * - * @return flag indicating if colourchanges propagated to all groups + * @return + * @see jalview.api.ViewStyleI#getColourAppliesToAllGroups() */ public boolean getColourAppliesToAllGroups() { - return colourAppliesToAllGroups; + return viewStyle.getColourAppliesToAllGroups(); } - boolean abovePIDThreshold = false; - /** - * GUI state - * - * @return true if percent identity threshold is applied to shading + * @return + * @see jalview.api.ViewStyleI#getAbovePIDThreshold() */ public boolean getAbovePIDThreshold() { - return abovePIDThreshold; + return viewStyle.getAbovePIDThreshold(); + } + + /** + * @param inc + * @see jalview.api.ViewStyleI#setIncrement(int) + */ + public void setIncrement(int inc) + { + viewStyle.setIncrement(inc); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getIncrement() + */ + public int getIncrement() + { + return viewStyle.getIncrement(); } /** - * GUI state - * - * * @param b - * indicate if percent identity threshold is applied to shading + * @see jalview.api.ViewStyleI#setConservationSelected(boolean) */ - public void setAbovePIDThreshold(boolean b) + public void setConservationSelected(boolean b) { - abovePIDThreshold = b; + viewStyle.setConservationSelected(b); } - int threshold; + /** + * @param show + * @see jalview.api.ViewStyleI#setShowHiddenMarkers(boolean) + */ + public void setShowHiddenMarkers(boolean show) + { + viewStyle.setShowHiddenMarkers(show); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getShowHiddenMarkers() + */ + public boolean getShowHiddenMarkers() + { + return viewStyle.getShowHiddenMarkers(); + } + + /** + * @param b + * @see jalview.api.ViewStyleI#setScaleRightWrapped(boolean) + */ + public void setScaleRightWrapped(boolean b) + { + viewStyle.setScaleRightWrapped(b); + } + + /** + * @param b + * @see jalview.api.ViewStyleI#setScaleLeftWrapped(boolean) + */ + public void setScaleLeftWrapped(boolean b) + { + viewStyle.setScaleLeftWrapped(b); + } + + /** + * @param b + * @see jalview.api.ViewStyleI#setScaleAboveWrapped(boolean) + */ + public void setScaleAboveWrapped(boolean b) + { + viewStyle.setScaleAboveWrapped(b); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getScaleLeftWrapped() + */ + public boolean getScaleLeftWrapped() + { + return viewStyle.getScaleLeftWrapped(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getScaleAboveWrapped() + */ + public boolean getScaleAboveWrapped() + { + return viewStyle.getScaleAboveWrapped(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getScaleRightWrapped() + */ + public boolean getScaleRightWrapped() + { + return viewStyle.getScaleRightWrapped(); + } + + /** + * @param b + * @see jalview.api.ViewStyleI#setAbovePIDThreshold(boolean) + */ + public void setAbovePIDThreshold(boolean b) + { + viewStyle.setAbovePIDThreshold(b); + } /** - * DOCUMENT ME! - * * @param thresh - * DOCUMENT ME! + * @see jalview.api.ViewStyleI#setThreshold(int) */ public void setThreshold(int thresh) { - threshold = thresh; + viewStyle.setThreshold(thresh); } /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! + * @return + * @see jalview.api.ViewStyleI#getThreshold() */ public int getThreshold() { - return threshold; + return viewStyle.getThreshold(); } - int increment; + /** + * @return + * @see jalview.api.ViewStyleI#getShowJVSuffix() + */ + public boolean getShowJVSuffix() + { + return viewStyle.getShowJVSuffix(); + } /** - * - * @param inc - * set the scalar for bleaching colourschemes according to degree of - * conservation + * @param b + * @see jalview.api.ViewStyleI#setShowJVSuffix(boolean) */ - public void setIncrement(int inc) + public void setShowJVSuffix(boolean b) { - increment = inc; + viewStyle.setShowJVSuffix(b); } /** - * GUI State - * - * @return get scalar for bleaching colourschemes by conservation + * @param state + * @see jalview.api.ViewStyleI#setWrapAlignment(boolean) */ - public int getIncrement() + public void setWrapAlignment(boolean state) { - return increment; + viewStyle.setWrapAlignment(state); } - boolean conservationColourSelected = false; + /** + * @param state + * @see jalview.api.ViewStyleI#setShowText(boolean) + */ + public void setShowText(boolean state) + { + viewStyle.setShowText(state); + } /** - * GUI state - * - * @return true if conservation based shading is enabled + * @param state + * @see jalview.api.ViewStyleI#setRenderGaps(boolean) */ - public boolean getConservationSelected() + public void setRenderGaps(boolean state) { - return conservationColourSelected; + viewStyle.setRenderGaps(state); } /** - * GUI state - * - * @param b - * enable conservation based shading + * @return + * @see jalview.api.ViewStyleI#getColourText() */ - public void setConservationSelected(boolean b) + public boolean getColourText() + { + return viewStyle.getColourText(); + } + + /** + * @param state + * @see jalview.api.ViewStyleI#setColourText(boolean) + */ + public void setColourText(boolean state) + { + viewStyle.setColourText(state); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getWrapAlignment() + */ + public boolean getWrapAlignment() + { + return viewStyle.getWrapAlignment(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getShowText() + */ + public boolean getShowText() + { + return viewStyle.getShowText(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getWrappedWidth() + */ + public int getWrappedWidth() + { + return viewStyle.getWrappedWidth(); + } + + /** + * @param w + * @see jalview.api.ViewStyleI#setWrappedWidth(int) + */ + public void setWrappedWidth(int w) + { + viewStyle.setWrappedWidth(w); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getCharHeight() + */ + public int getCharHeight() + { + return viewStyle.getCharHeight(); + } + + /** + * @param h + * @see jalview.api.ViewStyleI#setCharHeight(int) + */ + public void setCharHeight(int h) + { + viewStyle.setCharHeight(h); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getCharWidth() + */ + public int getCharWidth() + { + return viewStyle.getCharWidth(); + } + + /** + * @param w + * @see jalview.api.ViewStyleI#setCharWidth(int) + */ + public void setCharWidth(int w) + { + viewStyle.setCharWidth(w); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getShowBoxes() + */ + public boolean getShowBoxes() + { + return viewStyle.getShowBoxes(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getShowUnconserved() + */ + public boolean getShowUnconserved() + { + return viewStyle.getShowUnconserved(); + } + + /** + * @param showunconserved + * @see jalview.api.ViewStyleI#setShowUnconserved(boolean) + */ + public void setShowUnconserved(boolean showunconserved) + { + viewStyle.setShowUnconserved(showunconserved); + } + + /** + * @param default1 + * @see jalview.api.ViewStyleI#setSeqNameItalics(boolean) + */ + public void setSeqNameItalics(boolean default1) + { + viewStyle.setSeqNameItalics(default1); + } + + /** + * @param selected + * @see jalview.api.ViewStyleI#setShowSeqFeaturesHeight(boolean) + */ + public void setShowSeqFeaturesHeight(boolean selected) + { + viewStyle.setShowSeqFeaturesHeight(selected); + } + + /** + * alignment displayed in the viewport. Please use get/setter + */ + protected AlignmentI alignment; + + @Override + public AlignmentI getAlignment() { - conservationColourSelected = b; + return alignment; } @Override + public char getGapCharacter() + { + return alignment.getGapCharacter(); + } + + protected String sequenceSetID; + + /** + * probably unused indicator that view is of a dataset rather than an + * alignment + */ + protected boolean isDataset = false; + + public void setDataset(boolean b) + { + isDataset = b; + } + + public boolean isDataset() + { + return isDataset; + } + + + private Map hiddenRepSequences; + + protected ColumnSelection colSel = new ColumnSelection(); + + public boolean autoCalculateConsensus = true; + + protected boolean autoCalculateStrucConsensus = true; + + protected boolean ignoreGapsInConsensusCalculation = false; + + protected ColourSchemeI globalColourScheme = null; + + + @Override public void setGlobalColourScheme(ColourSchemeI cs) { // TODO: logic refactored from AlignFrame changeColour - @@ -221,7 +578,8 @@ public abstract class AlignmentViewport implements AlignViewportI || cs instanceof Blosum62ColourScheme) { recalc = true; - cs.setThreshold(threshold, ignoreGapsInConsensusCalculation); + cs.setThreshold(viewStyle.getThreshold(), + ignoreGapsInConsensusCalculation); } else { @@ -248,12 +606,13 @@ public abstract class AlignmentViewport implements AlignViewportI if (getAbovePIDThreshold() || cs instanceof PIDColourScheme || cs instanceof Blosum62ColourScheme) { - sg.cs.setThreshold(threshold, getIgnoreGapsConsensus()); + sg.cs.setThreshold(viewStyle.getThreshold(), + isIgnoreGapsConsensus()); recalc = true; } else { - sg.cs.setThreshold(0, getIgnoreGapsConsensus()); + sg.cs.setThreshold(0, isIgnoreGapsConsensus()); } if (getConservationSelected()) @@ -287,6 +646,8 @@ public abstract class AlignmentViewport implements AlignViewportI protected AlignmentAnnotation consensus; + protected AlignmentAnnotation complementConsensus; + protected AlignmentAnnotation strucConsensus; protected AlignmentAnnotation conservation; @@ -303,6 +664,11 @@ public abstract class AlignmentViewport implements AlignViewportI protected Hashtable[] hconsensus = null; /** + * results of cDNA complement consensus visible portion of view + */ + protected Hashtable[] hcomplementConsensus = null; + + /** * results of secondary structure base pair consensus for visible portion of * view */ @@ -332,7 +698,12 @@ public abstract class AlignmentViewport implements AlignViewportI public void setSequenceConsensusHash(Hashtable[] hconsensus) { this.hconsensus = hconsensus; + } + @Override + public void setComplementConsensusHash(Hashtable[] hconsensus) + { + this.hcomplementConsensus = hconsensus; } @Override @@ -342,6 +713,12 @@ public abstract class AlignmentViewport implements AlignViewportI } @Override + public Hashtable[] getComplementConsensusHash() + { + return hcomplementConsensus; + } + + @Override public Hashtable[] getRnaStructureConsensusHash() { return hStrucConsensus; @@ -373,6 +750,12 @@ public abstract class AlignmentViewport implements AlignViewportI } @Override + public AlignmentAnnotation getComplementConsensusAnnotation() + { + return complementConsensus; + } + + @Override public AlignmentAnnotation getAlignmentStrucConsensusAnnotation() { return strucConsensus; @@ -413,6 +796,20 @@ public abstract class AlignmentViewport implements AlignViewportI { calculator.registerWorker(new ConsensusThread(this, ap)); } + + /* + * A separate thread to compute cDNA consensus for a protein alignment + */ + final AlignmentI al = this.getAlignment(); + if (!al.isNucleotide() && al.getCodonFrames() != null + && !al.getCodonFrames().isEmpty()) + { + if (calculator + .getRegisteredWorkersOfClass(ComplementConsensusThread.class) == null) + { + calculator.registerWorker(new ComplementConsensusThread(this, ap)); + } + } } // --------START Structure Conservation @@ -517,6 +914,7 @@ public abstract class AlignmentViewport implements AlignViewportI // annotation update method from alignframe to viewport this.showSequenceLogo = showSequenceLogo; calculator.updateAnnotationFor(ConsensusThread.class); + calculator.updateAnnotationFor(ComplementConsensusThread.class); calculator.updateAnnotationFor(StrucConsensusThread.class); } this.showSequenceLogo = showSequenceLogo; @@ -576,39 +974,16 @@ public abstract class AlignmentViewport implements AlignViewportI return this.showConsensusHistogram; } - /** - * show non-conserved residues only - */ - protected boolean showUnconserved = false; - - /** - * when set, updateAlignment will always ensure sequences are of equal length - */ - private boolean padGaps = false; - - /** - * when set, alignment should be reordered according to a newly opened tree - */ - public boolean sortByTree = false; - - public boolean getShowUnconserved() - { - return showUnconserved; - } - - public void setShowUnconserved(boolean showunconserved) - { - showUnconserved = showunconserved; - } + /** + * when set, updateAlignment will always ensure sequences are of equal length + */ + private boolean padGaps = false; /** - * @param showNonconserved - * the showUnconserved to set + * when set, alignment should be reordered according to a newly opened tree */ - public void setShowunconserved(boolean displayNonconserved) - { - this.showUnconserved = displayNonconserved; - } + public boolean sortByTree = false; + /** * @@ -722,6 +1097,7 @@ public abstract class AlignmentViewport implements AlignViewportI */ protected String viewId = null; + @Override public String getViewId() { if (viewId == null) @@ -796,7 +1172,7 @@ public abstract class AlignmentViewport implements AlignViewportI } @Override - public boolean getIgnoreGapsConsensus() + public boolean isIgnoreGapsConsensus() { return ignoreGapsInConsensusCalculation; } @@ -813,7 +1189,11 @@ public abstract class AlignmentViewport implements AlignViewportI protected boolean showConsensus = true; - Hashtable sequenceColours; + private Map sequenceColours = new HashMap(); + + protected SequenceAnnotationOrder sortAnnotationsBy = null; + + protected boolean showAutocalculatedAbove; /** * Property change listener for changes in alignment @@ -1050,9 +1430,6 @@ public abstract class AlignmentViewport implements AlignViewportI } @Override - public abstract void sendSelection(); - - @Override public void invertColumnSelection() { colSel.invertColumnSelection(0, alignment.getWidth()); @@ -1074,10 +1451,8 @@ public abstract class AlignmentViewport implements AlignViewportI AlignmentAnnotation[] annots = alignment.getAlignmentAnnotation(); for (int i = 0; i < sequences.length; i++) { - sequences[i] = new Sequence(sequences[i], annots); // construct new - // sequence with - // subset of visible - // annotation + // construct new sequence with subset of visible annotation + sequences[i] = new Sequence(sequences[i], annots); } } else @@ -1106,10 +1481,10 @@ public abstract class AlignmentViewport implements AlignViewportI @Override - public jalview.datamodel.CigarArray getViewAsCigars( + public CigarArray getViewAsCigars( boolean selectedRegionOnly) { - return new jalview.datamodel.CigarArray(alignment, colSel, + return new CigarArray(alignment, colSel, (selectedRegionOnly ? selectionGroup : null)); } @@ -1171,9 +1546,9 @@ public abstract class AlignmentViewport implements AlignViewportI @Override - public int[][] getVisibleRegionBoundaries(int min, int max) + public List getVisibleRegionBoundaries(int min, int max) { - Vector regions = new Vector(); + ArrayList regions = new ArrayList(); int start = min; int end = max; @@ -1197,7 +1572,7 @@ public abstract class AlignmentViewport implements AlignViewportI } } - regions.addElement(new int[] + regions.add(new int[] { start, end }); if (colSel != null && colSel.hasHiddenColumns()) @@ -1209,10 +1584,7 @@ public abstract class AlignmentViewport implements AlignViewportI int[][] startEnd = new int[regions.size()][2]; - regions.copyInto(startEnd); - - return startEnd; - + return regions; } @Override @@ -1347,21 +1719,42 @@ public abstract class AlignmentViewport implements AlignViewportI { initRNAStructure(); } - initConsensus(); + consensus = new AlignmentAnnotation("Consensus", "PID", + new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); + initConsensus(consensus); + + initComplementConsensus(); } } - private void initConsensus() + /** + * If this is a protein alignment and there are mappings to cDNA, add the cDNA + * consensus annotation. + */ + protected void initComplementConsensus() { + if (!alignment.isNucleotide()) + { + final Set codonMappings = alignment + .getCodonFrames(); + if (codonMappings != null && !codonMappings.isEmpty()) + { + complementConsensus = new AlignmentAnnotation("cDNA Consensus", + "PID for cDNA", new Annotation[1], 0f, 100f, + AlignmentAnnotation.BAR_GRAPH); + initConsensus(complementConsensus); + } + } + } - consensus = new AlignmentAnnotation("Consensus", "PID", - new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); - consensus.hasText = true; - consensus.autoCalculated = true; + private void initConsensus(AlignmentAnnotation aa) + { + aa.hasText = true; + aa.autoCalculated = true; if (showConsensus) { - alignment.addAnnotation(consensus); + alignment.addAnnotation(aa); } } @@ -1423,57 +1816,57 @@ public abstract class AlignmentViewport implements AlignViewportI public int calcPanelHeight() { // setHeight of panels - AlignmentAnnotation[] aa = getAlignment().getAlignmentAnnotation(); + AlignmentAnnotation[] anns = getAlignment().getAlignmentAnnotation(); int height = 0; int charHeight = getCharHeight(); - if (aa != null) + if (anns != null) { BitSet graphgrp = new BitSet(); - for (int i = 0; i < aa.length; i++) + for (AlignmentAnnotation aa : anns) { - if (aa[i] == null) + if (aa == null) { System.err.println("Null annotation row: ignoring."); continue; } - if (!aa[i].visible) + if (!aa.visible) { continue; } - if (aa[i].graphGroup > -1) + if (aa.graphGroup > -1) { - if (graphgrp.get(aa[i].graphGroup)) + if (graphgrp.get(aa.graphGroup)) { continue; } else { - graphgrp.set(aa[i].graphGroup); + graphgrp.set(aa.graphGroup); } } - aa[i].height = 0; + aa.height = 0; - if (aa[i].hasText) + if (aa.hasText) { - aa[i].height += charHeight; + aa.height += charHeight; } - if (aa[i].hasIcons) + if (aa.hasIcons) { - aa[i].height += 16; + aa.height += 16; } - if (aa[i].graph > 0) + if (aa.graph > 0) { - aa[i].height += aa[i].graphHeight; + aa.height += aa.graphHeight; } - if (aa[i].height == 0) + if (aa.height == 0) { - aa[i].height = 20; + aa.height = 20; } - height += aa[i].height; + height += aa.height; } } if (height == 0) @@ -1551,60 +1944,34 @@ public abstract class AlignmentViewport implements AlignViewportI } oldrfs.clear(); } - /** - * show the reference sequence in the alignment view - */ - private boolean displayReferenceSeq=false; - /** - * colour according to the reference sequence defined on the alignment - */ - private boolean colourByReferenceSeq=false; - @Override public boolean isDisplayReferenceSeq() { - return alignment.hasSeqrep() && displayReferenceSeq; + return alignment.hasSeqrep() && viewStyle.isDisplayReferenceSeq(); } @Override public void setDisplayReferenceSeq(boolean displayReferenceSeq) { - this.displayReferenceSeq = displayReferenceSeq; + viewStyle.setDisplayReferenceSeq(displayReferenceSeq); } + @Override public boolean isColourByReferenceSeq() { - return alignment.hasSeqrep() && colourByReferenceSeq; - } - - public void setColourByReferenceSeq(boolean colourByReferenceSeq) - { - this.colourByReferenceSeq = colourByReferenceSeq; + return alignment.hasSeqrep() && viewStyle.isColourByReferenceSeq(); } @Override public Color getSequenceColour(SequenceI seq) { - Color sqc = Color.white; - if (sequenceColours != null) - { - sqc = (Color) sequenceColours.get(seq); - if (sqc == null) - { - sqc = Color.white; - } - } - return sqc; + Color sqc = sequenceColours.get(seq); + return (sqc == null ? Color.white : sqc); } @Override public void setSequenceColour(SequenceI seq, Color col) { - if (sequenceColours == null) - { - sequenceColours = new Hashtable(); - } - if (col == null) { sequenceColours.remove(seq); @@ -1618,10 +1985,6 @@ public abstract class AlignmentViewport implements AlignViewportI @Override public void updateSequenceIdColours() { - if (sequenceColours == null) - { - sequenceColours = new Hashtable(); - } for (SequenceGroup sg : alignment.getGroups()) { if (sg.idColour != null) @@ -1637,10 +2000,42 @@ public abstract class AlignmentViewport implements AlignViewportI @Override public void clearSequenceColours() { - sequenceColours = null; + sequenceColours.clear(); }; - FeaturesDisplayedI featuresDisplayed = null; + @Override + public AlignViewportI getCodingComplement() + { + return this.codingComplement; + } + + /** + * Set this as the (cDna/protein) complement of the given viewport. Also + * ensures the reverse relationship is set on the given viewport. + */ + @Override + public void setCodingComplement(AlignViewportI av) + { + if (this == av) + { + System.err.println("Ignoring recursive setCodingComplement request"); + } + else + { + this.codingComplement = av; + // avoid infinite recursion! + if (av.getCodingComplement() != this) + { + av.setCodingComplement(this); + } + } + } + + @Override + public boolean isNucleotide() + { + return getAlignment() == null ? false : getAlignment().isNucleotide(); + } @Override public FeaturesDisplayedI getFeaturesDisplayed() @@ -1661,11 +2056,6 @@ public abstract class AlignmentViewport implements AlignViewportI } /** - * display setting for showing/hiding sequence features on alignment view - */ - boolean showSequenceFeatures = false; - - /** * set the flag * * @param b @@ -1674,55 +2064,351 @@ public abstract class AlignmentViewport implements AlignViewportI @Override public void setShowSequenceFeatures(boolean b) { - showSequenceFeatures = b; + viewStyle.setShowSequenceFeatures(b); } @Override public boolean isShowSequenceFeatures() { - return showSequenceFeatures; + return viewStyle.isShowSequenceFeatures(); } - boolean showSeqFeaturesHeight; - @Override public void setShowSequenceFeaturesHeight(boolean selected) { - showSeqFeaturesHeight = selected; + viewStyle.setShowSeqFeaturesHeight(selected); } @Override public boolean isShowSequenceFeaturesHeight() { - return showSeqFeaturesHeight; + return viewStyle.isShowSequenceFeaturesHeight(); } - private boolean showAnnotation = true; - - private boolean rightAlignIds = false; @Override public void setShowAnnotation(boolean b) { - showAnnotation = b; + viewStyle.setShowAnnotation(b); } @Override public boolean isShowAnnotation() { - return showAnnotation; + return viewStyle.isShowAnnotation(); } @Override public boolean isRightAlignIds() { - return rightAlignIds; + return viewStyle.isRightAlignIds(); } @Override public void setRightAlignIds(boolean rightAlignIds) { - this.rightAlignIds = rightAlignIds; + viewStyle.setRightAlignIds(rightAlignIds); + } + + @Override + public boolean getConservationSelected() + { + return viewStyle.getConservationSelected(); + } + + @Override + public void setShowBoxes(boolean state) + { + viewStyle.setShowBoxes(state); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getTextColour() + */ + public Color getTextColour() + { + return viewStyle.getTextColour(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getTextColour2() + */ + public Color getTextColour2() + { + return viewStyle.getTextColour2(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getThresholdTextColour() + */ + public int getThresholdTextColour() + { + return viewStyle.getThresholdTextColour(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#isConservationColourSelected() + */ + public boolean isConservationColourSelected() + { + return viewStyle.isConservationColourSelected(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#isRenderGaps() + */ + public boolean isRenderGaps() + { + return viewStyle.isRenderGaps(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#isShowColourText() + */ + public boolean isShowColourText() + { + return viewStyle.isShowColourText(); + } + /** + * @return + * @see jalview.api.ViewStyleI#isShowSeqFeaturesHeight() + */ + public boolean isShowSeqFeaturesHeight() + { + return viewStyle.isShowSeqFeaturesHeight(); + } + + /** + * @param conservationColourSelected + * @see jalview.api.ViewStyleI#setConservationColourSelected(boolean) + */ + public void setConservationColourSelected( + boolean conservationColourSelected) + { + viewStyle.setConservationColourSelected(conservationColourSelected); + } + + /** + * @param showColourText + * @see jalview.api.ViewStyleI#setShowColourText(boolean) + */ + public void setShowColourText(boolean showColourText) + { + viewStyle.setShowColourText(showColourText); + } + + /** + * @param textColour + * @see jalview.api.ViewStyleI#setTextColour(java.awt.Color) + */ + public void setTextColour(Color textColour) + { + viewStyle.setTextColour(textColour); + } + + /** + * @param thresholdTextColour + * @see jalview.api.ViewStyleI#setThresholdTextColour(int) + */ + public void setThresholdTextColour(int thresholdTextColour) + { + viewStyle.setThresholdTextColour(thresholdTextColour); + } + + /** + * @param textColour2 + * @see jalview.api.ViewStyleI#setTextColour2(java.awt.Color) + */ + public void setTextColour2(Color textColour2) + { + viewStyle.setTextColour2(textColour2); + } + + @Override + public ViewStyleI getViewStyle() + { + return new ViewStyle(viewStyle); + } + + @Override + public void setViewStyle(ViewStyleI settingsForView) + { + viewStyle = new ViewStyle(settingsForView); + } + + @Override + public boolean sameStyle(ViewStyleI them) + { + return viewStyle.sameStyle(them); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getIdWidth() + */ + public int getIdWidth() + { + return viewStyle.getIdWidth(); + } + + /** + * @param i + * @see jalview.api.ViewStyleI#setIdWidth(int) + */ + public void setIdWidth(int i) + { + viewStyle.setIdWidth(i); + } + + /** + * @return + * @see jalview.api.ViewStyleI#isCentreColumnLabels() + */ + public boolean isCentreColumnLabels() + { + return viewStyle.isCentreColumnLabels(); + } + + /** + * @param centreColumnLabels + * @see jalview.api.ViewStyleI#setCentreColumnLabels(boolean) + */ + public void setCentreColumnLabels(boolean centreColumnLabels) + { + viewStyle.setCentreColumnLabels(centreColumnLabels); + } + + /** + * @param showdbrefs + * @see jalview.api.ViewStyleI#setShowDBRefs(boolean) + */ + public void setShowDBRefs(boolean showdbrefs) + { + viewStyle.setShowDBRefs(showdbrefs); + } + + /** + * @return + * @see jalview.api.ViewStyleI#isShowDBRefs() + */ + public boolean isShowDBRefs() + { + return viewStyle.isShowDBRefs(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#isShowNPFeats() + */ + public boolean isShowNPFeats() + { + return viewStyle.isShowNPFeats(); + } + + /** + * @param shownpfeats + * @see jalview.api.ViewStyleI#setShowNPFeats(boolean) + */ + public void setShowNPFeats(boolean shownpfeats) + { + viewStyle.setShowNPFeats(shownpfeats); + } + + public abstract StructureSelectionManager getStructureSelectionManager(); + + /** + * Add one command to the command history list. + * + * @param command + */ + public void addToHistoryList(CommandI command) + { + if (this.historyList != null) + { + this.historyList.push(command); + broadcastCommand(command, false); + } + } + + protected void broadcastCommand(CommandI command, boolean undo) + { + getStructureSelectionManager().commandPerformed(command, undo, getVamsasSource()); + } + + /** + * Add one command to the command redo list. + * + * @param command + */ + public void addToRedoList(CommandI command) + { + if (this.redoList != null) + { + this.redoList.push(command); + } + broadcastCommand(command, true); + } + + /** + * Clear the command redo list. + */ + public void clearRedoList() + { + if (this.redoList != null) + { + this.redoList.clear(); + } + } + + public void setHistoryList(Deque list) + { + this.historyList = list; + } + + public Deque getHistoryList() + { + return this.historyList; + } + + public void setRedoList(Deque list) + { + this.redoList = list; + } + + public Deque getRedoList() + { + return this.redoList; + } + + @Override + public VamsasSource getVamsasSource() + { + return this; + } + + public SequenceAnnotationOrder getSortAnnotationsBy() + { + return sortAnnotationsBy; } + public void setSortAnnotationsBy(SequenceAnnotationOrder sortAnnotationsBy) + { + this.sortAnnotationsBy = sortAnnotationsBy; + } + + public boolean isShowAutocalculatedAbove() + { + return showAutocalculatedAbove; + } + + public void setShowAutocalculatedAbove(boolean showAutocalculatedAbove) + { + this.showAutocalculatedAbove = showAutocalculatedAbove; + } } diff --git a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java index c7cee04..674f3d1 100644 --- a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java +++ b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java @@ -247,12 +247,6 @@ public abstract class FeatureRendererModel implements ArrayList tmp = new ArrayList(); SequenceFeature[] features = sequence.getSequenceFeatures(); - while (features == null && sequence.getDatasetSequence() != null) - { - sequence = sequence.getDatasetSequence(); - features = sequence.getSequenceFeatures(); - } - if (features != null) { for (int i = 0; i < features.length; i++) @@ -329,9 +323,7 @@ public abstract class FeatureRendererModel implements for (int i = 0; i < alignment.getHeight(); i++) { SequenceI asq = alignment.getSequenceAt(i); - SequenceI dasq = asq.getDatasetSequence(); - SequenceFeature[] features = dasq != null ? dasq - .getSequenceFeatures() : asq.getSequenceFeatures(); + SequenceFeature[] features = asq.getSequenceFeatures(); if (features == null) { diff --git a/src/jalview/viewmodel/styles/ViewStyle.java b/src/jalview/viewmodel/styles/ViewStyle.java new file mode 100644 index 0000000..1e97af4 --- /dev/null +++ b/src/jalview/viewmodel/styles/ViewStyle.java @@ -0,0 +1,1007 @@ +package jalview.viewmodel.styles; + +import jalview.api.ViewStyleI; + +import java.awt.Color; +import java.lang.reflect.Method; +import java.util.HashMap; + +/** + * A container for holding alignment view properties. View properties are + * data-independent, which means they can be safely copied between views + * involving different alignment data without causing exceptions in the + * rendering system. + * + * @author jprocter + * + */ +public class ViewStyle implements ViewStyleI +{ + + private boolean abovePIDThreshold = false; + + int charHeight; + + int charWidth; + + int idWidth = -1; + + /** + * gui state - changes to colour scheme propagated to all groups + */ + private boolean colourAppliesToAllGroups; + + /** + * centre columnar annotation labels in displayed alignment annotation + */ + boolean centreColumnLabels = false; + + private boolean showdbrefs; + + private boolean shownpfeats; + + // --------END Structure Conservation + + /** + * colour according to the reference sequence defined on the alignment + */ + private boolean colourByReferenceSeq = false; + + boolean conservationColourSelected = false; + + /** + * show the reference sequence in the alignment view + */ + private boolean displayReferenceSeq = false; + + private int increment; + + /** + * display gap characters + */ + boolean renderGaps = true; + + private boolean rightAlignIds = false; + + boolean scaleAboveWrapped = false; + + boolean scaleLeftWrapped = true; + + boolean scaleRightWrapped = true; + + boolean seqNameItalics; + + /** + * show annotation tracks on the alignment + */ + private boolean showAnnotation = true; + + /** + * render each residue in a coloured box + */ + boolean showBoxes = true; + + /** + * Colour sequence text + */ + boolean showColourText = false; + + /** + * show blue triangles + */ + boolean showHiddenMarkers = true; + + /** + * show /start-end in ID panel + */ + boolean showJVSuffix = true; + + /** + * scale features height according to score + */ + boolean showSeqFeaturesHeight; + + /** + * display setting for showing/hiding sequence features on alignment view + */ + boolean showSequenceFeatures = false; + + /** + * display sequence symbols + */ + boolean showText = true; + + /** + * show non-conserved residues only + */ + protected boolean showUnconserved = false; + + Color textColour = Color.black; + + Color textColour2 = Color.white; + + /** + * PID or consensus threshold + */ + int threshold; + + /** + * threshold for switching between textColour & textColour2 + */ + int thresholdTextColour = 0; + + /** + * upper case characters in sequence are shown in bold + */ + boolean upperCasebold = false; + + /** + * name of base font for view + */ + private String fontName; + /** + * size for base font + */ + private int fontSize; + + public ViewStyle(ViewStyleI viewStyle) + { + ViewStyle.configureFrom(this, viewStyle); + } + + public ViewStyle() + { + } + + private static HashMap getters, isErs, setters; + static + { + getters = new HashMap(); + isErs = new HashMap(); + setters = new HashMap(); + // Match Getters and Setters + for (Method m : ViewStyleI.class.getMethods()) + { + if (m.getDeclaringClass() == ViewStyleI.class) + { + if (m.getName().startsWith("get")) + { + getters.put(m.getName().substring(3), m); + } + if (m.getName().startsWith("is")) + { + isErs.put(m.getName().substring(2), m); + } + if (m.getName().startsWith("set")) + { + setters.put(m.getName().substring(3), m); + } + } + } + } + + private static void configureFrom(ViewStyle us, ViewStyleI viewStyle) + { + // try and do the set thing + for (String prop : setters.keySet()) + { + Method getter = getters.get(prop); + Method setter = setters.get(prop); + if (getter == null) + { + getter = isErs.get(prop); + } + if (getter != null && setter != null) + { + try + { + setter.invoke(us, getter.invoke(viewStyle)); + } catch (Exception q) + { + System.err.println("Unexpected exception setting view property " + + prop + " by reflection"); + q.printStackTrace(); + } + + } + } + } + + private static boolean equivalent(ViewStyle us, ViewStyleI them) + { + // look for properties we can set + for (String prop : setters.keySet()) + { + Method getter = getters.get(prop); + if (getter == null) + { + getter = isErs.get(prop); + } + if (getter != null) + { + try + { + if (!getter.invoke(them).equals(getter.invoke(us))) + { + return false; + } + } catch (Exception q) + { + System.err.println("Unexpected exception testing equivalence of property " + + prop + " by reflection"); + q.printStackTrace(); + } + } + } + + return true; + } + + public boolean equals(ViewStyleI other) + { + return other == null ? false : equivalent(this, other); + } + + /** + * @return the upperCasebold + */ + @Override + public boolean isUpperCasebold() + { + return upperCasebold; + } + + /** + * @param upperCasebold + * the upperCasebold to set + */ + @Override + public void setUpperCasebold(boolean upperCasebold) + { + this.upperCasebold = upperCasebold; + } + + /** + * flag for wrapping + */ + boolean wrapAlignment = false; + + /** + * number columns in wrapped alignment + */ + int wrappedWidth; + + private int fontStyle; + + /** + * GUI state + * + * @return true if percent identity threshold is applied to shading + */ + @Override + public boolean getAbovePIDThreshold() + { + return abovePIDThreshold; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public int getCharHeight() + { + return charHeight; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public int getCharWidth() + { + return charWidth; + } + + /** + * + * + * @return flag indicating if colourchanges propagated to all groups + */ + @Override + public boolean getColourAppliesToAllGroups() + { + return colourAppliesToAllGroups; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public boolean getColourText() + { + return showColourText; + } + + /** + * GUI state + * + * @return true if conservation based shading is enabled + */ + @Override + public boolean getConservationSelected() + { + return conservationColourSelected; + } + + /** + * GUI State + * + * @return get scalar for bleaching colourschemes by conservation + */ + @Override + public int getIncrement() + { + return increment; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public boolean getScaleAboveWrapped() + { + return scaleAboveWrapped; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public boolean getScaleLeftWrapped() + { + return scaleLeftWrapped; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public boolean getScaleRightWrapped() + { + return scaleRightWrapped; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public boolean getShowBoxes() + { + return showBoxes; + } + + @Override + public boolean getShowHiddenMarkers() + { + return showHiddenMarkers; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public boolean getShowJVSuffix() + { + return showJVSuffix; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public boolean getShowText() + { + return showText; + } + + @Override + public boolean getShowUnconserved() + { + return showUnconserved; + } + + /** + * @return the textColour + */ + @Override + public Color getTextColour() + { + return textColour; + } + + /** + * @return the textColour2 + */ + @Override + public Color getTextColour2() + { + return textColour2; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public int getThreshold() + { + return threshold; + } + + /** + * @return the thresholdTextColour + */ + @Override + public int getThresholdTextColour() + { + return thresholdTextColour; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public boolean getWrapAlignment() + { + return wrapAlignment; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + @Override + public int getWrappedWidth() + { + return wrappedWidth; + } + + @Override + public boolean isColourByReferenceSeq() + { + return colourByReferenceSeq; + } + + /** + * @return the conservationColourSelected + */ + @Override + public boolean isConservationColourSelected() + { + return conservationColourSelected; + } + + @Override + public boolean isDisplayReferenceSeq() + { + return displayReferenceSeq; + } + + /** + * @return the renderGaps + */ + @Override + public boolean isRenderGaps() + { + return renderGaps; + } + + @Override + public boolean isRightAlignIds() + { + return rightAlignIds; + } + + /** + * @return the seqNameItalics + */ + @Override + public boolean isSeqNameItalics() + { + return seqNameItalics; + } + + @Override + public boolean isShowAnnotation() + { + return showAnnotation; + } + + /** + * @return the showColourText + */ + @Override + public boolean isShowColourText() + { + return showColourText; + } + + /** + * @return the showSeqFeaturesHeight + */ + @Override + public boolean isShowSeqFeaturesHeight() + { + return showSeqFeaturesHeight; + } + + @Override + public boolean isShowSequenceFeatures() + { + return showSequenceFeatures; + } + + @Override + public boolean isShowSequenceFeaturesHeight() + { + + return showSeqFeaturesHeight; + } + + /** + * GUI state + * + * + * @param b + * indicate if percent identity threshold is applied to shading + */ + @Override + public void setAbovePIDThreshold(boolean b) + { + abovePIDThreshold = b; + } + + + /** + * DOCUMENT ME! + * + * @param h + * DOCUMENT ME! + */ + @Override + public void setCharHeight(int h) + { + this.charHeight = h; + } + + /** + * DOCUMENT ME! + * + * @param w + * DOCUMENT ME! + */ + @Override + public void setCharWidth(int w) + { + this.charWidth = w; + } + + + /** + * @param value + * indicating if subsequent colourscheme changes will be propagated + * to all groups + */ + @Override + public void setColourAppliesToAllGroups(boolean b) + { + colourAppliesToAllGroups = b; + } + + @Override + public void setColourByReferenceSeq(boolean colourByReferenceSeq) + { + this.colourByReferenceSeq = colourByReferenceSeq; + } + + /** + * DOCUMENT ME! + * + * @param state + * DOCUMENT ME! + */ + @Override + public void setColourText(boolean state) + { + showColourText = state; + } + + /** + * @param conservationColourSelected + * the conservationColourSelected to set + */ + @Override + public void setConservationColourSelected( + boolean conservationColourSelected) + { + this.conservationColourSelected = conservationColourSelected; + } + + /** + * GUI state + * + * @param b + * enable conservation based shading + */ + @Override + public void setConservationSelected(boolean b) + { + conservationColourSelected = b; + } + + @Override + public void setDisplayReferenceSeq(boolean displayReferenceSeq) + { + this.displayReferenceSeq = displayReferenceSeq; + } + + /** + * + * @param inc + * set the scalar for bleaching colourschemes according to degree of + * conservation + */ + @Override + public void setIncrement(int inc) + { + increment = inc; + } + + /** + * DOCUMENT ME! + * + * @param state + * DOCUMENT ME! + */ + @Override + public void setRenderGaps(boolean state) + { + renderGaps = state; + } + + @Override + public void setRightAlignIds(boolean rightAlignIds) + { + this.rightAlignIds = rightAlignIds; + } + + /** + * DOCUMENT ME! + * + * @param b + * DOCUMENT ME! + */ + @Override + public void setScaleAboveWrapped(boolean b) + { + scaleAboveWrapped = b; + } + + /** + * DOCUMENT ME! + * + * @param b + * DOCUMENT ME! + */ + @Override + public void setScaleLeftWrapped(boolean b) + { + scaleLeftWrapped = b; + } + + /** + * + * + * @param scaleRightWrapped + * - true or false + */ + + @Override + public void setScaleRightWrapped(boolean b) + { + scaleRightWrapped = b; + } + + @Override + public void setSeqNameItalics(boolean italics) + { + seqNameItalics = italics; + } + + @Override + public void setShowAnnotation(boolean b) + { + showAnnotation = b; + } + + /** + * DOCUMENT ME! + * + * @param state + * DOCUMENT ME! + */ + @Override + public void setShowBoxes(boolean state) + { + showBoxes = state; + } + + /** + * @param showColourText + * the showColourText to set + */ + @Override + public void setShowColourText(boolean showColourText) + { + this.showColourText = showColourText; + } + + @Override + public void setShowHiddenMarkers(boolean show) + { + showHiddenMarkers = show; + } + + /** + * DOCUMENT ME! + * + * @param b + * DOCUMENT ME! + */ + @Override + public void setShowJVSuffix(boolean b) + { + showJVSuffix = b; + } + + @Override + public void setShowSeqFeaturesHeight(boolean selected) + { + showSeqFeaturesHeight = selected; + + } + + /** + * set the flag + * + * @param b + * features are displayed if true + */ + @Override + public void setShowSequenceFeatures(boolean b) + { + showSequenceFeatures = b; + } + + /** + * DOCUMENT ME! + * + * @param state + * DOCUMENT ME! + */ + @Override + public void setShowText(boolean state) + { + showText = state; + } + + @Override + public void setShowUnconserved(boolean showunconserved) + { + showUnconserved = showunconserved; + } + + /** + * @param textColour + * the textColour to set + */ + @Override + public void setTextColour(Color textColour) + { + this.textColour = textColour; + } + + /** + * @param textColour2 + * the textColour2 to set + */ + @Override + public void setTextColour2(Color textColour2) + { + this.textColour2 = textColour2; + } + + /** + * DOCUMENT ME! + * + * @param thresh + * DOCUMENT ME! + */ + @Override + public void setThreshold(int thresh) + { + threshold = thresh; + } + + /** + * @param thresholdTextColour + * the thresholdTextColour to set + */ + @Override + public void setThresholdTextColour(int thresholdTextColour) + { + this.thresholdTextColour = thresholdTextColour; + } + + /** + * DOCUMENT ME! + * + * @param state + * DOCUMENT ME! + */ + @Override + public void setWrapAlignment(boolean state) + { + wrapAlignment = state; + } + + /** + * DOCUMENT ME! + * + * @param w + * DOCUMENT ME! + */ + @Override + public void setWrappedWidth(int w) + { + this.wrappedWidth = w; + } + + @Override + public boolean sameStyle(ViewStyleI them) + { + return equivalent(this, them); + } + + @Override + public String getFontName() + { + return fontName; + } + + @Override + public int getFontSize() + { + return fontSize; + } + + @Override + public int getFontStyle() + { + return fontStyle; + } + + @Override + public void setFontName(String name) + { + fontName = name; + } + + @Override + public void setFontSize(int size) + { + fontSize = size; + + } + + @Override + public void setFontStyle(int style) + { + fontStyle = style; + } + + @Override + public int getIdWidth() + { + return idWidth; + } + + /** + * @param idWidth + * the idWidth to set + */ + @Override + public void setIdWidth(int idWidth) + { + this.idWidth = idWidth; + } + + /** + * @return the centreColumnLabels + */ + @Override + public boolean isCentreColumnLabels() + { + return centreColumnLabels; + } + + /** + * @param centreColumnLabels + * the centreColumnLabels to set + */ + @Override + public void setCentreColumnLabels(boolean centreColumnLabels) + { + this.centreColumnLabels = centreColumnLabels; + } + + /** + * @return the showdbrefs + */ + @Override + public boolean isShowDBRefs() + { + return showdbrefs; + } + + /** + * @param showdbrefs + * the showdbrefs to set + */ + @Override + public void setShowDBRefs(boolean showdbrefs) + { + this.showdbrefs = showdbrefs; + } + + /** + * @return the shownpfeats + */ + @Override + public boolean isShowNPFeats() + { + return shownpfeats; + } + + /** + * @param shownpfeats + * the shownpfeats to set + */ + @Override + public void setShowNPFeats(boolean shownpfeats) + { + this.shownpfeats = shownpfeats; + } +} diff --git a/src/jalview/workers/AlignCalcManager.java b/src/jalview/workers/AlignCalcManager.java index dd25593..1063706 100644 --- a/src/jalview/workers/AlignCalcManager.java +++ b/src/jalview/workers/AlignCalcManager.java @@ -20,6 +20,10 @@ */ package jalview.workers; +import jalview.api.AlignCalcManagerI; +import jalview.api.AlignCalcWorkerI; +import jalview.datamodel.AlignmentAnnotation; + import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -28,10 +32,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import jalview.api.AlignCalcManagerI; -import jalview.api.AlignCalcWorkerI; -import jalview.datamodel.AlignmentAnnotation; - public class AlignCalcManager implements AlignCalcManagerI { private volatile List restartable = Collections @@ -256,10 +256,12 @@ public class AlignCalcManager implements AlignCalcManagerI for (List workers : updating.values()) { for (AlignCalcWorkerI worker : workers) + { if (worker.involves(alignmentAnnotation)) { return true; } + } } } return false; @@ -291,7 +293,7 @@ public class AlignCalcManager implements AlignCalcManagerI AlignCalcWorkerI[] workers; synchronized (canUpdate) { - workers = canUpdate.toArray(new AlignCalcWorkerI[0]); + workers = canUpdate.toArray(new AlignCalcWorkerI[canUpdate.size()]); } for (AlignCalcWorkerI worker : workers) { diff --git a/src/jalview/workers/ComplementConsensusThread.java b/src/jalview/workers/ComplementConsensusThread.java new file mode 100644 index 0000000..2e4424e --- /dev/null +++ b/src/jalview/workers/ComplementConsensusThread.java @@ -0,0 +1,68 @@ +package jalview.workers; + +import java.util.Hashtable; + +import jalview.analysis.AAFrequency; +import jalview.api.AlignViewportI; +import jalview.api.AlignmentViewPanel; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SequenceI; + +/** + * A thread to recompute the consensus of the cDNA complement for a linked + * protein alignment. + * + * @author gmcarstairs + * + */ +public class ComplementConsensusThread extends ConsensusThread +{ + + public ComplementConsensusThread(AlignViewportI alignViewport, + AlignmentViewPanel alignPanel) + { + super(alignViewport, alignPanel); + } + + @Override + protected AlignmentAnnotation getConsensusAnnotation() + { + return alignViewport.getComplementConsensusAnnotation(); + } + + @Override + protected Hashtable[] getViewportConsensus() + { + return alignViewport.getComplementConsensusHash(); + } + + @Override + protected void computeConsensus(AlignmentI alignment) + { + Hashtable[] hconsensus = new Hashtable[alignment.getWidth()]; + + SequenceI[] aseqs = getSequences(); + AAFrequency.calculateCdna(alignment, hconsensus); + + alignViewport.setComplementConsensusHash(hconsensus); + } + + /** + * Convert the computed consensus data into the desired annotation for + * display. + * + * @param consensusAnnotation + * the annotation to be populated + * @param consensusData + * the computed consensus data + */ + @Override + protected void deriveConsensus(AlignmentAnnotation consensusAnnotation, + Hashtable[] consensusData) + { + AAFrequency.completeCdnaConsensus(consensusAnnotation, consensusData, + alignViewport.isShowSequenceLogo(), getSequences().length); + } + +} diff --git a/src/jalview/workers/ConsensusThread.java b/src/jalview/workers/ConsensusThread.java index 8cde493..f244242 100644 --- a/src/jalview/workers/ConsensusThread.java +++ b/src/jalview/workers/ConsensusThread.java @@ -20,6 +20,8 @@ */ package jalview.workers; +import java.util.Hashtable; + import jalview.analysis.AAFrequency; import jalview.api.AlignCalcWorkerI; import jalview.api.AlignViewportI; @@ -30,13 +32,9 @@ import jalview.datamodel.Annotation; import jalview.datamodel.SequenceI; import jalview.schemes.ColourSchemeI; -import java.util.Hashtable; - public class ConsensusThread extends AlignCalcWorker implements AlignCalcWorkerI { - private long nseq = -1; - public ConsensusThread(AlignViewportI alignViewport, AlignmentViewPanel alignPanel) { @@ -54,8 +52,7 @@ public class ConsensusThread extends AlignCalcWorker implements long started = System.currentTimeMillis(); try { - AlignmentAnnotation consensus = alignViewport - .getAlignmentConsensusAnnotation(); + AlignmentAnnotation consensus = getConsensusAnnotation(); if (consensus == null || calcMan.isPending(this)) { calcMan.workerComplete(this); @@ -88,58 +85,90 @@ public class ConsensusThread extends AlignCalcWorker implements if (alignment == null || (aWidth = alignment.getWidth()) < 0) { calcMan.workerComplete(this); - // .updatingConservation = false; - // AlignViewport.UPDATING_CONSERVATION = false; - return; } - consensus = alignViewport.getAlignmentConsensusAnnotation(); - consensus.annotations = null; - consensus.annotations = new Annotation[aWidth]; - Hashtable[] hconsensus = alignViewport.getSequenceConsensusHash(); - hconsensus = new Hashtable[aWidth]; - try - { - SequenceI aseqs[] = alignment.getSequencesArray(); - nseq = aseqs.length; - AAFrequency.calculate(aseqs, 0, alignment.getWidth(), hconsensus, - true); - } catch (ArrayIndexOutOfBoundsException x) - { - // this happens due to a race condition - - // alignment was edited at same time as calculation was running - // - // calcMan.workerCannotRun(this); - calcMan.workerComplete(this); - return; - } - alignViewport.setSequenceConsensusHash(hconsensus); + eraseConsensus(aWidth); + computeConsensus(alignment); updateResultAnnotation(true); - ColourSchemeI globalColourScheme = alignViewport - .getGlobalColourScheme(); - if (globalColourScheme != null) + + if (ap != null) { - globalColourScheme.setConsensus(hconsensus); + ap.paintAlignment(true); } - } catch (OutOfMemoryError error) { calcMan.workerCannotRun(this); - - // consensus = null; - // hconsensus = null; ap.raiseOOMWarning("calculating consensus", error); + } finally + { + /* + * e.g. ArrayIndexOutOfBoundsException can happen due to a race condition + * - alignment was edited at same time as calculation was running + */ + calcMan.workerComplete(this); } + } + + /** + * Clear out any existing consensus annotations + * + * @param aWidth + * the width (number of columns) of the annotated alignment + */ + protected void eraseConsensus(int aWidth) + { + AlignmentAnnotation consensus = getConsensusAnnotation(); + consensus.annotations = new Annotation[aWidth]; + } + + /** + * @param alignment + */ + protected void computeConsensus(AlignmentI alignment) + { + Hashtable[] hconsensus = new Hashtable[alignment.getWidth()]; + + SequenceI[] aseqs = getSequences(); + AAFrequency.calculate(aseqs, 0, alignment.getWidth(), hconsensus, + true); - calcMan.workerComplete(this); - if (ap != null) + alignViewport.setSequenceConsensusHash(hconsensus); + setColourSchemeConsensus(hconsensus); + } + + /** + * @return + */ + protected SequenceI[] getSequences() + { + return alignViewport.getAlignment().getSequencesArray(); + } + + /** + * @param hconsensus + */ + protected void setColourSchemeConsensus(Hashtable[] hconsensus) + { + ColourSchemeI globalColourScheme = alignViewport + .getGlobalColourScheme(); + if (globalColourScheme != null) { - ap.paintAlignment(true); + globalColourScheme.setConsensus(hconsensus); } } /** + * Get the Consensus annotation for the alignment + * + * @return + */ + protected AlignmentAnnotation getConsensusAnnotation() + { + return alignViewport.getAlignmentConsensusAnnotation(); + } + + /** * update the consensus annotation from the sequence profile data using * current visualization settings. */ @@ -151,15 +180,40 @@ public class ConsensusThread extends AlignCalcWorker implements public void updateResultAnnotation(boolean immediate) { - AlignmentAnnotation consensus = alignViewport - .getAlignmentConsensusAnnotation(); - Hashtable[] hconsensus = alignViewport.getSequenceConsensusHash(); + AlignmentAnnotation consensus = getConsensusAnnotation(); + Hashtable[] hconsensus = getViewportConsensus(); if (immediate || !calcMan.isWorking(this) && consensus != null && hconsensus != null) { - AAFrequency.completeConsensus(consensus, hconsensus, 0, - hconsensus.length, alignViewport.getIgnoreGapsConsensus(), - alignViewport.isShowSequenceLogo(), nseq); + deriveConsensus(consensus, hconsensus); } } + + /** + * Convert the computed consensus data into the desired annotation for + * display. + * + * @param consensusAnnotation + * the annotation to be populated + * @param consensusData + * the computed consensus data + */ + protected void deriveConsensus(AlignmentAnnotation consensusAnnotation, + Hashtable[] consensusData) + { + long nseq = getSequences().length; + AAFrequency.completeConsensus(consensusAnnotation, consensusData, 0, + consensusData.length, alignViewport.isIgnoreGapsConsensus(), + alignViewport.isShowSequenceLogo(), nseq); + } + + /** + * Get the consensus data stored on the viewport. + * + * @return + */ + protected Hashtable[] getViewportConsensus() + { + return alignViewport.getSequenceConsensusHash(); + } } diff --git a/src/jalview/workers/StrucConsensusThread.java b/src/jalview/workers/StrucConsensusThread.java index 02d584a..4471b6e 100644 --- a/src/jalview/workers/StrucConsensusThread.java +++ b/src/jalview/workers/StrucConsensusThread.java @@ -166,7 +166,7 @@ public class StrucConsensusThread extends AlignCalcWorker implements { StructureFrequency.completeConsensus(strucConsensus, hStrucConsensus, 0, hStrucConsensus.length, - alignViewport.getIgnoreGapsConsensus(), + alignViewport.isIgnoreGapsConsensus(), alignViewport.isShowSequenceLogo(), nseq); } } diff --git a/src/jalview/ws/AWSThread.java b/src/jalview/ws/AWSThread.java index 74b118c..e557614 100644 --- a/src/jalview/ws/AWSThread.java +++ b/src/jalview/ws/AWSThread.java @@ -28,8 +28,11 @@ import jalview.datamodel.AlignmentView; import jalview.datamodel.SequenceI; import jalview.gui.AlignFrame; import jalview.gui.WebserviceInfo; -import jalview.viewmodel.seqfeatures.FeatureRendererSettings; import jalview.util.MessageManager; +import jalview.viewmodel.seqfeatures.FeatureRendererSettings; + +import java.util.LinkedHashSet; +import java.util.Set; public abstract class AWSThread extends Thread { @@ -57,7 +60,7 @@ public abstract class AWSThread extends Thread /** * dataset sequence relationships to be propagated onto new results */ - protected AlignedCodonFrame[] codonframe = null; + protected Set codonframe = null; /** * are there jobs still running in this thread. @@ -87,6 +90,11 @@ public abstract class AWSThread extends Thread */ protected String WsUrl = null; + /* + * The AlignFrame from which the service was requested. + */ + private AlignFrame alignFrame; + /** * generic web service job/subjob poll loop */ @@ -124,8 +132,9 @@ public abstract class AWSThread extends Thread } catch (Exception ex) { // Deal with Transaction exceptions - wsInfo.appendProgressText(jobs[j].jobnum, - MessageManager.formatMessage("info.server_exception", new String[]{WebServiceName,ex.getMessage()})); + wsInfo.appendProgressText(jobs[j].jobnum, MessageManager + .formatMessage("info.server_exception", new Object[] + { WebServiceName, ex.getMessage() })); // always output the exception's stack trace to the log Cache.log.warn(WebServiceName + " job(" + jobs[j].jobnum + ") Server exception."); @@ -189,7 +198,7 @@ public abstract class AWSThread extends Thread { Cache.log .debug("WebServiceJob poll loop finished with no jobs created."); - wsInfo.setStatus(wsInfo.STATE_STOPPED_ERROR); + wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR); wsInfo.appendProgressText(MessageManager.getString("info.no_jobs_ran")); wsInfo.setFinishedNoResults(); } @@ -295,13 +304,12 @@ public abstract class AWSThread extends Thread SequenceI[] alignment = al.getSequencesArray(); for (int sq = 0; sq < alignment.length; sq++) { - for (int i = 0; i < codonframe.length; i++) + for (AlignedCodonFrame acf : codonframe) { - if (codonframe[i] != null - && codonframe[i].involvesSequence(alignment[sq])) + final SequenceI seq = alignment[sq]; + if (acf != null && acf.involvesSequence(seq)) { - al.addCodonFrame(codonframe[i]); - codonframe[i] = null; + al.addCodonFrame(acf); break; } } @@ -360,7 +368,7 @@ public abstract class AWSThread extends Thread AlignmentView alview, String wsurl2) { super(); - // this.alignFrame = alframe; + this.alignFrame = alframe; currentView = alframe.getCurrentView().getAlignment(); featureSettings = alframe.getFeatureRenderer().getSettings(); defGapChar = alframe.getViewport().getGapCharacter(); @@ -369,13 +377,18 @@ public abstract class AWSThread extends Thread WsUrl = wsurl2; if (alframe != null) { - AlignedCodonFrame[] cf = alframe.getViewport().getAlignment() + Set cf = alframe.getViewport().getAlignment() .getCodonFrames(); if (cf != null) { - codonframe = new AlignedCodonFrame[cf.length]; - System.arraycopy(cf, 0, codonframe, 0, cf.length); + codonframe = new LinkedHashSet(); + codonframe.addAll(cf); } } } + + protected AlignFrame getRequestingAlignFrame() + { + return this.alignFrame; + } } diff --git a/src/jalview/ws/HttpClientUtils.java b/src/jalview/ws/HttpClientUtils.java index c416aa5..c6d6629 100644 --- a/src/jalview/ws/HttpClientUtils.java +++ b/src/jalview/ws/HttpClientUtils.java @@ -43,6 +43,7 @@ import org.apache.http.entity.mime.content.StringBody; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.CoreProtocolPNames; +import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; /** @@ -65,12 +66,23 @@ public class HttpClientUtils * @throws Exception */ public static BufferedReader doHttpUrlPost(String postUrl, - List vals) throws ClientProtocolException, + List vals, int connectionTimeoutMs, + int readTimeoutMs) throws ClientProtocolException, IOException { + // todo use HttpClient 4.3 or later and class RequestConfig HttpParams params = new BasicHttpParams(); params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); + if (connectionTimeoutMs > 0) + { + HttpConnectionParams + .setConnectionTimeout(params, connectionTimeoutMs); + } + if (readTimeoutMs > 0) + { + HttpConnectionParams.setSoTimeout(params, readTimeoutMs); + } HttpClient httpclient = new DefaultHttpClient(params); HttpPost httppost = new HttpPost(postUrl); UrlEncodedFormEntity ue = new UrlEncodedFormEntity(vals, "UTF-8"); diff --git a/src/jalview/ws/SequenceFetcher.java b/src/jalview/ws/SequenceFetcher.java index 33afd10..9c42f0a 100644 --- a/src/jalview/ws/SequenceFetcher.java +++ b/src/jalview/ws/SequenceFetcher.java @@ -20,6 +20,11 @@ */ package jalview.ws; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Vector; + import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentI; import jalview.datamodel.DBRefSource; @@ -28,11 +33,6 @@ import jalview.ws.dbsources.das.api.jalviewSourceI; import jalview.ws.seqfetcher.ASequenceFetcher; import jalview.ws.seqfetcher.DbSourceProxy; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.Vector; - /** * This is the the concrete implementation of the sequence retrieval interface * and abstract class in jalview.ws.seqfetcher. This implements the run-time @@ -61,10 +61,8 @@ public class SequenceFetcher extends ASequenceFetcher addDBRefSourceImpl(jalview.ws.dbsources.UnprotName.class); addDBRefSourceImpl(jalview.ws.dbsources.Pdb.class); addDBRefSourceImpl(jalview.ws.dbsources.PfamFull.class); - addDBRefSourceImpl(jalview.ws.dbsources.PfamSeed.class); // ensures Seed - // alignment is - // 'default' for - // PFAM + addDBRefSourceImpl(jalview.ws.dbsources.PfamSeed.class); + // ensures Seed alignment is 'default' for PFAM addDBRefSourceImpl(jalview.ws.dbsources.RfamFull.class); addDBRefSourceImpl(jalview.ws.dbsources.RfamSeed.class); if (addDas) @@ -285,7 +283,9 @@ public class SequenceFetcher extends ASequenceFetcher String db = dbSources[dbsource]; // skip me if (db.equals(DBRefSource.PDB)) + { continue; + } for (DbSourceProxy sp : sfetcher.getSourceProxy(db)) { System.out.println("Source: " + sp.getDbName() + " (" + db @@ -348,9 +348,13 @@ public class SequenceFetcher extends ASequenceFetcher System.out.println("ERROR:No alignment retrieved."); StringBuffer raw = sp.getRawRecords(); if (raw != null) + { System.out.println(raw.toString()); + } else + { System.out.println("ERROR:No Raw results."); + } } else { diff --git a/src/jalview/ws/dbsources/PDBRestClient.java b/src/jalview/ws/dbsources/PDBRestClient.java new file mode 100644 index 0000000..1ab6125 --- /dev/null +++ b/src/jalview/ws/dbsources/PDBRestClient.java @@ -0,0 +1,338 @@ +package jalview.ws.dbsources; + +import jalview.ws.uimodel.PDBRestRequest; +import jalview.ws.uimodel.PDBRestResponse; +import jalview.ws.uimodel.PDBRestResponse.PDBResponseSummary; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import javax.ws.rs.core.MediaType; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.config.ClientConfig; +import com.sun.jersey.api.client.config.DefaultClientConfig; +import com.sun.jersey.api.json.JSONConfiguration; + +/** + * A rest client for querying the Search endpoing of the PDB REST API + * + * @author tcnofoegbu + * + */ +public class PDBRestClient +{ + private static String PDB_SEARCH_ENDPOINT = "http://wwwdev.ebi.ac.uk/pdbe/search/pdb/select?"; + + private static int DEFAULT_RESPONSE_SIZE = 200; + + /** + * Takes a PDBRestRequest object and returns a response upon execution + * + * @param pdbRestRequest + * the PDBRestRequest instance to be processed + * @return the pdbResponse object for the given request + */ + public PDBRestResponse executeRequest(PDBRestRequest pdbRestRequest) + { + ClientConfig clientConfig = new DefaultClientConfig(); + clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, + Boolean.TRUE); + Client client = Client.create(clientConfig); + + String wantedFields = getPDBDocFieldsAsCommaDelimitedString(pdbRestRequest + .getWantedFields()); + int responseSize = (pdbRestRequest.getResponseSize() == 0) ? DEFAULT_RESPONSE_SIZE + : pdbRestRequest.getResponseSize(); + String sortParam = (pdbRestRequest.getFieldToSortBy() == null || pdbRestRequest + .getFieldToSortBy().trim().isEmpty()) ? "" : (pdbRestRequest + .getFieldToSortBy() + (pdbRestRequest.isAscending() ? " asc" + : " desc")); + + // Build request parameters for the REST Request + WebResource webResource = client.resource(PDB_SEARCH_ENDPOINT) + .queryParam("wt", "json").queryParam("fl", wantedFields) + .queryParam("rows", String.valueOf(responseSize)) + .queryParam("q", pdbRestRequest.getQuery()) + .queryParam("sort", sortParam); + + // Execute the REST request + ClientResponse clientResponse = webResource.accept( + MediaType.APPLICATION_JSON).get(ClientResponse.class); + + // Get the JSON string from the response object + String responseString = clientResponse.getEntity(String.class); + + // Check the response status and report exception if one occurs + if (clientResponse.getStatus() != 200) + { + String errorMessage = ""; + if (clientResponse.getStatus() == 400) + { + errorMessage = parseJsonExceptionString(responseString); + throw new RuntimeException(errorMessage); + } + else + { + errorMessage = "Failed : HTTP error code : " + + clientResponse.getStatus(); + throw new RuntimeException(errorMessage); + } + } + + // Make redundant objects eligible for garbage collection to conserve + // memory + clientResponse = null; + client = null; + + // Process the response and return the result to the caller. + return parsePDBJsonResponse(responseString, pdbRestRequest); + } + + /** + * Process error response from PDB server if/when one occurs. + * + * @param jsonResponse + * the JSON string containing error message from the server + * @return the processed error message from the JSON string + */ + public static String parseJsonExceptionString(String jsonErrorResponse) + { + String errorMessage = "RunTime error"; + try + { + JSONParser jsonParser = new JSONParser(); + JSONObject jsonObj = (JSONObject) jsonParser.parse(jsonErrorResponse); + JSONObject errorResponse = (JSONObject) jsonObj.get("error"); + errorMessage = errorResponse.get("msg").toString(); + + JSONObject responseHeader = (JSONObject) jsonObj + .get("responseHeader"); + errorMessage += responseHeader.get("params").toString(); + } catch (ParseException e) + { + e.printStackTrace(); + } + return errorMessage; + } + + /** + * Parses the JSON response string from PDB REST API. The response is dynamic + * hence, only fields specifically requested for in the 'wantedFields' + * parameter is fetched/processed + * + * @param pdbJsonResponseString + * the JSON string to be parsed + * @param pdbRestRequest + * the request object which contains parameters used to process the + * JSON string + * @return + */ + @SuppressWarnings("unchecked") + public static PDBRestResponse parsePDBJsonResponse( + String pdbJsonResponseString, PDBRestRequest pdbRestRequest) + { + PDBRestResponse searchResult = new PDBRestResponse(); + List result = null; + try + { + JSONParser jsonParser = new JSONParser(); + JSONObject jsonObj = (JSONObject) jsonParser + .parse(pdbJsonResponseString); + + JSONObject pdbResponse = (JSONObject) jsonObj.get("response"); + String queryTime = ((JSONObject) jsonObj.get("responseHeader")).get( + "QTime").toString(); + int numFound = Integer + .valueOf(pdbResponse.get("numFound").toString()); + if (numFound > 0) + { + result = new ArrayList(); + JSONArray docs = (JSONArray) pdbResponse.get("docs"); + for (Iterator docIter = docs.iterator(); docIter + .hasNext();) + { + JSONObject doc = docIter.next(); + result.add(searchResult.new PDBResponseSummary(doc, + pdbRestRequest)); + } + searchResult.setNumberOfItemsFound(numFound); + searchResult.setResponseTime(queryTime); + searchResult.setSearchSummary(result); + } + } catch (ParseException e) + { + e.printStackTrace(); + } + return searchResult; + } + + /** + * Takes a collection of PDBDocField and converts its 'code' Field values into + * a comma delimited string. + * + * @param pdbDocfields + * the collection of PDBDocField to process + * @return the comma delimited string from the pdbDocFields collection + */ + public static String getPDBDocFieldsAsCommaDelimitedString( + Collection pdbDocfields) + { + String result = ""; + if (pdbDocfields != null && !pdbDocfields.isEmpty()) + { + StringBuilder returnedFields = new StringBuilder(); + for (PDBDocField field : pdbDocfields) + { + returnedFields.append(",").append(field.getCode()); + } + returnedFields.deleteCharAt(0); + result = returnedFields.toString(); + } + return result; + } + + /** + * Determines the column index for 'PDB Id' Fields in the dynamic summary + * table. The PDB Id serves as a unique identifier for a given row in the + * summary table + * + * @param wantedFeilds + * the available table columns in no particular order + * @return the pdb id field column index + */ + public static int getPDBIdColumIndex( + Collection wantedFeilds, boolean hasRefSeq) + { + + // If a reference sequence is attached then start counting from 1 else + // start from zero + int pdbFeildIndexCounter = hasRefSeq ? 1 : 0; + + for (PDBDocField feild : wantedFeilds) + { + if (feild.equals(PDBDocField.PDB_ID)) + { + break; // Once PDB Id index is determined exit iteration + } + ++pdbFeildIndexCounter; + } + return pdbFeildIndexCounter; + } + + /** + * This enum represents the fields available in the PDB JSON response + * + */ + public enum PDBDocField + { + PDB_ID("PDB Id", "pdb_id"), TITLE("Title", "title"), MOLECULE_NAME( + "Molecule", "molecule_name"), MOLECULE_TYPE("Molecule Type", + "molecule_type"), MOLECULE_SEQUENCE("Sequence", + "molecule_sequence"), PFAM_ACCESSION("PFAM Accession", + "pfam_accession"), PFAM_NAME("PFAM Name", "pfam_name"), INTERPRO_NAME( + "InterPro Name", "interpro_name"), INTERPRO_ACCESSION( + "InterPro Accession", "interpro_accession"), UNIPROT_ID( + "UniProt Id", "uniprot_id"), UNIPROT_ACCESSION( + "UniProt Accession", "uniprot_accession"), UNIPROT_COVERAGE( + "UniProt Coverage", "uniprot_coverage"), UNIPROT_FEATURES( + "Uniprot Features", "uniprot_features"), R_FACTOR("R Factor", + "r_factor"), RESOLUTION("Resolution", "resolution"), DATA_QUALITY( + "Data Quality", "data_quality"), OVERALL_QUALITY( + "Overall Quality", "overall_quality"), POLYMER_COUNT( + "Number of Polymers", "number_of_polymers"), PROTEIN_CHAIN_COUNT( + "Number of Protein Chains", "number_of_protein_chains"), BOUND_MOLECULE_COUNT( + "Number of Bound Molecule", "number_of_bound_molecules"), POLYMER_RESIDUE_COUNT( + "Number of Polymer Residue", "number_of_polymer_residues"), GENUS( + "GENUS", "genus"), GENE_NAME("Gene Name", "gene_name"), EXPERIMENTAL_METHOD( + "Experimental Method", "experimental_method"), GO_ID("GO Id", + "go_id"), ASSEMBLY_ID("Assembly Id", "assembly_form"), ASSEMBLY_FORM( + "Assembly Form", "assembly_id"), ASSEMBLY_TYPE("Assembly Type", + "assembly_type"), SPACE_GROUP("Space Group", "spacegroup"), CATH_CODE( + "Cath Code", "cath_code"), TAX_ID("Tax Id", "tax_id"), TAX_QUERY( + "Tax Query", "tax_query"), INTERACTING_ENTRY_ID( + "Interacting Entry Id", "interacting_entry_id"), INTERACTING_ENTITY_ID( + "Interacting Entity Id", "interacting_entity_id"), INTERACTING_MOLECULES( + "Interacting Molecules", "interacting_molecules"), PUBMED_ID( + "Pubmed Id", "pubmed_id"), STATUS("Status", "status"), MODEL_QUALITY( + "Model Quality", "model_quality"), PIVOT_RESOLUTION( + "Pivot Resolution", "pivot_resolution"), DATA_REDUCTION_SOFTWARE( + "Data reduction software", "data_reduction_software"), MAX_OBSERVED_RES( + "Max observed residues", "max_observed_residues"), ORG_SCI_NAME( + "Organism scientific name", "organism_scientific_name"), SUPER_KINGDOM( + "Super kingdom", "superkingdom"), RANK("Rank", "rank"), CRYSTALLISATION_PH( + "Crystallisation Ph", "crystallisation_ph"), BIOLOGICAL_FUNCTION( + "Biological Function", "biological_function"), BIOLOGICAL_PROCESS( + "Biological Process", "biological_process"), BIOLOGICAL_CELL_COMPONENT( + "Biological Cell Component", "biological_cell_component"), COMPOUND_NAME( + "Compound Name", "compound_name"), COMPOUND_ID("Compound Id", + "compound_id"), COMPOUND_WEIGHT("Compound Weight", + "compound_weight"), COMPOUND_SYSTEMATIC_NAME( + "Compound Systematic Name", "compound_systematic_name"), INTERACTING_LIG( + "Interacting Ligands", "interacting_ligands"), JOURNAL( + "Journal", "journal"), ALL_AUTHORS("All Authors", "all_authors"), EXPERIMENTAL_DATA_AVAILABLE( + "Experiment Data Available", "experiment_data_available"), DIFFRACTION_PROTOCOL( + "Diffraction Protocol", "diffraction_protocol"), REFINEMENT_SOFTWARE( + "Refinement Software", "refinement_software"), STRUCTURE_DETERMINATION_METHOD( + "Structure Determination Method", + "structure_determination_method"), SYNCHROTON_SITE( + "Synchrotron Site", "synchrotron_site"), SAMPLE_PREP_METHOD( + "Sample Preparation Method", "sample_preparation_method"), ENTRY_AUTHORS( + "Entry Authors", "entry_authors"), CITATION_TITLE( + "Citation Title", "citation_title"), STRUCTURE_SOLUTION_SOFTWARE( + "Structure Solution Software", "structure_solution_software"), ENTRY_ENTITY( + "Entry Entity", "entry_entity"), R_FREE("R Free", "r_free"), NO_OF_POLYMER_ENTITIES( + "Number of Polymer Entities", "number_of_polymer_entities"), NO_OF_BOUND_ENTITIES( + "Number of Bound Entities", "number_of_bound_entities"), CRYSTALLISATION_RESERVOIR( + "Crystallisation Reservoir", "crystallisation_reservoir"), DATA_SCALING_SW( + "Data Scalling Software", "data_scaling_software"), DETECTOR( + "Detector", "detector"), DETECTOR_TYPE("Detector Type", + "detector_type"), MODIFIED_RESIDUE_FLAG( + "Modified Residue Flag", "modified_residue_flag"), NUMBER_OF_COPIES( + "Number of Copies", "number_of_copies"), STRUCT_ASYM_ID( + "Struc Asym Id", "struct_asym_id"), HOMOLOGUS_PDB_ENTITY_ID( + "Homologus PDB Entity Id", "homologus_pdb_entity_id"), MOLECULE_SYNONYM( + "Molecule Synonym", "molecule_synonym"), DEPOSITION_SITE( + "Deposition Site", "deposition_site"), SYNCHROTRON_BEAMLINE( + "Synchrotron Beamline", "synchrotron_beamline"), ENTITY_ID( + "Entity Id", "entity_id"), BEAM_SOURCE_NAME("Beam Source Name", + "beam_source_name"), PROCESSING_SITE("Processing Site", + "processing_site"), ENTITY_WEIGHT("Entity Weight", + "entity_weight"), VERSION("Version", "_version_"), ALL("ALL", + "text"); + + private String name; + + private String code; + + PDBDocField(String name, String code) + { + this.name = name; + this.code = code; + } + + public String getName() + { + return name; + } + + public String getCode() + { + return code; + } + + public String toString() + { + return name; + } + } +} \ No newline at end of file diff --git a/src/jalview/ws/jws2/JPred301Client.java b/src/jalview/ws/jws2/JPred301Client.java index b086159..db70fa0 100644 --- a/src/jalview/ws/jws2/JPred301Client.java +++ b/src/jalview/ws/jws2/JPred301Client.java @@ -35,6 +35,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import compbio.data.sequence.FastaSequence; import compbio.data.sequence.JpredAlignment; @@ -90,15 +92,18 @@ public class JPred301Client extends JabawsMsaInterfaceAlignCalcWorker return "calculating consensus secondary structure prediction using JPred service"; } - private static HashMap jpredRowLabels = new HashMap(); + private static Map jpredRowLabels = new HashMap(); - private static HashSet jpredRes_graph, jpredRes_ssonly; + private static final Set jpredRes_graph; + + private static final Set jpredRes_ssonly; + static { - jpredRes_ssonly = new HashSet(); + jpredRes_ssonly = new HashSet(); jpredRes_ssonly.add("jnetpred".toLowerCase()); jpredRes_ssonly.add("jnetpssm".toLowerCase()); jpredRes_ssonly.add("jnethmm".toLowerCase()); - jpredRes_graph = new HashSet(); + jpredRes_graph = new HashSet(); jpredRes_graph.add("jnetconf".toLowerCase()); jpredRes_graph.add("jnet burial".toLowerCase()); } diff --git a/src/jalview/ws/jws2/MsaWSThread.java b/src/jalview/ws/jws2/MsaWSThread.java index 3a16248..d0d0a6e 100644 --- a/src/jalview/ws/jws2/MsaWSThread.java +++ b/src/jalview/ws/jws2/MsaWSThread.java @@ -23,6 +23,7 @@ package jalview.ws.jws2; import jalview.analysis.AlignSeq; import jalview.bin.Cache; import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentI; import jalview.datamodel.AlignmentOrder; import jalview.datamodel.AlignmentView; import jalview.datamodel.ColumnSelection; @@ -30,6 +31,7 @@ import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; import jalview.gui.AlignFrame; import jalview.gui.Desktop; +import jalview.gui.SplitFrame; import jalview.gui.WebserviceInfo; import jalview.util.MessageManager; import jalview.ws.AWsJob; @@ -44,6 +46,8 @@ import java.util.List; import java.util.Map; import java.util.Vector; +import javax.swing.JInternalFrame; + import compbio.data.msa.MsaWS; import compbio.metadata.Argument; import compbio.metadata.ChunkHolder; @@ -447,7 +451,7 @@ class MsaWSThread extends AWS2Thread implements WSClientI * @param presorder * boolean */ - MsaWSThread(MsaWS server, String wsUrl, WebserviceInfo wsinfo, + private MsaWSThread(MsaWS server, String wsUrl, WebserviceInfo wsinfo, jalview.gui.AlignFrame alFrame, AlignmentView alview, String wsname, boolean subgaps, boolean presorder) { @@ -892,10 +896,16 @@ class MsaWSThread extends AWS2Thread implements WSClientI wsInfo.setProgressBar(null, progbar); } + /** + * Display alignment results in a new frame (or - not currently supported - + * added to an existing alignment). + * + * @param newFrame + */ void displayResults(boolean newFrame) { // view input or result data for each block - Vector alorders = new Vector(); + List alorders = new ArrayList(); SequenceI[][] results = new SequenceI[jobs.length][]; AlignmentOrder[] orders = new AlignmentOrder[jobs.length]; String lastProgram = null; @@ -907,7 +917,7 @@ class MsaWSThread extends AWS2Thread implements WSClientI msjob = (MsaWSJob) jobs[j]; Object[] res = msjob.getAlignment(); lastProgram = msjob.getAlignmentProgram(); - alorders.add(res[1]); + alorders.add((AlignmentOrder) res[1]); results[j] = (SequenceI[]) res[0]; orders[j] = (AlignmentOrder) res[1]; @@ -944,71 +954,126 @@ class MsaWSThread extends AWS2Thread implements WSClientI if (newFrame) { - AlignFrame af = new AlignFrame(al, columnselection, - AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); + displayInNewFrame(al, alorders, columnselection); - // initialise with same renderer settings as in parent alignframe. - af.getFeatureRenderer().transferSettings(this.featureSettings); - // update orders - if (alorders.size() > 0) - { - if (alorders.size() == 1) - { - af.addSortByOrderMenuItem(WebServiceName + " Ordering", - (AlignmentOrder) alorders.get(0)); - } - else - { - // construct a non-redundant ordering set - Vector names = new Vector(); - for (int i = 0, l = alorders.size(); i < l; i++) - { - String orderName = new String(" Region " + i); - int j = i + 1; + } + else + { + System.out.println("MERGE WITH OLD FRAME"); + // TODO: modify alignment in original frame, replacing old for new + // alignment using the commands.EditCommand model to ensure the update can + // be undone + } + } - while (j < l) - { - if (((AlignmentOrder) alorders.get(i)) - .equals(((AlignmentOrder) alorders.get(j)))) - { - alorders.remove(j); - l--; - orderName += "," + j; - } - else - { - j++; - } - } + /** + * Display the alignment result in a new frame. + * + * @param al + * @param alorders + * @param columnselection + */ + protected void displayInNewFrame(AlignmentI al, + List alorders, ColumnSelection columnselection) + { + AlignFrame af = new AlignFrame(al, columnselection, + AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); - if (i == 0 && j == 1) - { - names.add(new String("")); - } - else - { - names.add(orderName); - } - } - for (int i = 0, l = alorders.size(); i < l; i++) - { - af.addSortByOrderMenuItem( - WebServiceName + ((String) names.get(i)) + " Ordering", - (AlignmentOrder) alorders.get(i)); - } - } + // initialise with same renderer settings as in parent alignframe. + af.getFeatureRenderer().transferSettings(this.featureSettings); + + if (alorders.size() > 0) + { + addSortByMenuItems(af, alorders); + } + + /* + * If alignment was requested from one half of a SplitFrame, show in a + * SplitFrame with the other pane similarly aligned. + */ + AlignFrame requestedBy = getRequestingAlignFrame(); + if (requestedBy != null && requestedBy.getSplitViewContainer() != null) + { + AlignmentI complement = requestedBy.getSplitViewContainer() + .getComplement(requestedBy); + String complementTitle = requestedBy.getSplitViewContainer() + .getComplementTitle(requestedBy); + AlignmentI copyComplement = new Alignment(complement); + copyComplement.alignAs(al); + if (copyComplement.getHeight() > 0) + { + af.setTitle(alTitle); + AlignFrame af2 = new AlignFrame(copyComplement, + AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); + af2.setTitle(complementTitle); + String linkedTitle = MessageManager + .getString("label.linked_view_title"); + JInternalFrame splitFrame = new SplitFrame(al.isNucleotide() ? af + : af2, al.isNucleotide() ? af2 : af); + Desktop.addInternalFrame(splitFrame, linkedTitle, -1, -1); + return; } + } - Desktop.addInternalFrame(af, alTitle, AlignFrame.DEFAULT_WIDTH, - AlignFrame.DEFAULT_HEIGHT); + /* + * Not from SplitFrame, or failed to created a complementary alignment + */ + Desktop.addInternalFrame(af, alTitle, AlignFrame.DEFAULT_WIDTH, + AlignFrame.DEFAULT_HEIGHT); + } + /** + * Add sort order options to the AlignFrame menus. + * + * @param af + * @param alorders + */ + protected void addSortByMenuItems(AlignFrame af, + List alorders) + { + // update orders + if (alorders.size() == 1) + { + af.addSortByOrderMenuItem(WebServiceName + " Ordering", + alorders.get(0)); } else { - System.out.println("MERGE WITH OLD FRAME"); - // TODO: modify alignment in original frame, replacing old for new - // alignment using the commands.EditCommand model to ensure the update can - // be undone + // construct a non-redundant ordering set + List names = new ArrayList(); + for (int i = 0, l = alorders.size(); i < l; i++) + { + String orderName = " Region " + i; + int j = i + 1; + + while (j < l) + { + if (alorders.get(i).equals(alorders.get(j))) + { + alorders.remove(j); + l--; + orderName += "," + j; + } + else + { + j++; + } + } + + if (i == 0 && j == 1) + { + names.add(""); + } + else + { + names.add(orderName); + } + } + for (int i = 0, l = alorders.size(); i < l; i++) + { + af.addSortByOrderMenuItem(WebServiceName + (names.get(i)) + + " Ordering", alorders.get(i)); + } } } diff --git a/src/jalview/ws/rest/InputType.java b/src/jalview/ws/rest/InputType.java index 91fce18..8741ddc 100644 --- a/src/jalview/ws/rest/InputType.java +++ b/src/jalview/ws/rest/InputType.java @@ -46,6 +46,8 @@ import org.apache.http.entity.mime.content.StringBody; */ public abstract class InputType { + private static final Pattern URL_PATTERN = Pattern.compile("^([^=]+)=?'?([^']*)?'?"); + /** * not used yet */ @@ -209,7 +211,7 @@ public abstract class InputType boolean valid = true; for (String tok : tokenstring) { - Matcher mtch = Pattern.compile("^([^=]+)=?'?([^']*)?'?").matcher(tok); + Matcher mtch = URL_PATTERN.matcher(tok); if (mtch.find()) { try diff --git a/src/jalview/ws/uimodel/PDBRestRequest.java b/src/jalview/ws/uimodel/PDBRestRequest.java new file mode 100644 index 0000000..58d7aeb --- /dev/null +++ b/src/jalview/ws/uimodel/PDBRestRequest.java @@ -0,0 +1,142 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2) + * Copyright (C) 2014 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 . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ + +package jalview.ws.uimodel; + + +import jalview.ws.dbsources.PDBRestClient.PDBDocField; + +import java.util.Collection; + +/** + * Represents the PDB request to be consumed by the PDBRestClient + * + * @author tcnofoegbu + * + */ +public class PDBRestRequest +{ + private String fieldToSearchBy; + + private String searchTerm; + + private String fieldToSortBy; + + private String associatedSequence; + + private boolean allowEmptySequence; + + private int responseSize; + + private boolean isSortAscending; + + private Collection wantedFields;// = new + // Collection(); + + public String getFieldToSearchBy() + { + return fieldToSearchBy; + } + + public void setFieldToSearchBy(String fieldToSearchBy) + { + this.fieldToSearchBy = fieldToSearchBy; + } + + public String getSearchTerm() + { + return searchTerm; + } + + public void setSearchTerm(String searchTerm) + { + this.searchTerm = searchTerm; + } + + public boolean isAllowEmptySeq() + { + return allowEmptySequence; + } + + public void setAllowEmptySeq(boolean allowEmptySeq) + { + this.allowEmptySequence = allowEmptySeq; + } + + public int getResponseSize() + { + return responseSize; + } + + public void setResponseSize(int responseSize) + { + this.responseSize = responseSize; + } + + public Collection getWantedFields() + { + return wantedFields; + } + + public void setWantedFields(Collection wantedFields) + { + this.wantedFields = wantedFields; + } + + public String getFieldToSortBy() + { + return fieldToSortBy; + } + + public void setFieldToSortBy(String fieldToSortBy, boolean isSortAscending) + { + this.fieldToSortBy = fieldToSortBy; + this.isSortAscending = isSortAscending; + } + + public boolean isAscending() + { + return isSortAscending; + } + + public String getAssociatedSequence() + { + return associatedSequence; + } + + public void setAssociatedSequence(String associatedSequence) + { + this.associatedSequence = associatedSequence; + } + + public String getQuery() + { + return fieldToSearchBy + searchTerm + + (isAllowEmptySeq() ? "" : " AND molecule_sequence:['' TO *]"); + } + + public String toString() + { + return "Query : " + getQuery() + " sort field: " + fieldToSortBy + + " isAsc: " + isAscending() + " Associated Seq : " + + associatedSequence; + } +} diff --git a/src/jalview/ws/uimodel/PDBRestResponse.java b/src/jalview/ws/uimodel/PDBRestResponse.java new file mode 100644 index 0000000..3b5b05c --- /dev/null +++ b/src/jalview/ws/uimodel/PDBRestResponse.java @@ -0,0 +1,220 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2) + * Copyright (C) 2014 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 . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ + +package jalview.ws.uimodel; + +import jalview.ws.dbsources.PDBRestClient.PDBDocField; + +import java.util.Collection; +import java.util.Objects; + +import javax.swing.table.DefaultTableModel; + +import org.json.simple.JSONObject; + +/** + * Represents the response model produced by the PDBRestClient upon successful + * execution of a given request + * + * @author tcnofoegbu + * + */ +public class PDBRestResponse +{ + private int numberOfItemsFound; + + private String responseTime; + + private Collection searchSummary; + + public int getNumberOfItemsFound() + { + return numberOfItemsFound; + } + + public void setNumberOfItemsFound(int itemFound) + { + this.numberOfItemsFound = itemFound; + } + + public String getResponseTime() + { + return responseTime; + } + + public void setResponseTime(String responseTime) + { + this.responseTime = responseTime; + } + + public Collection getSearchSummary() + { + return searchSummary; + } + + public void setSearchSummary(Collection searchSummary) + { + this.searchSummary = searchSummary; + } + + + /** + * Convenience method to obtain a Table model for a given summary List based + * on the request parameters + * + * @param request + * the PDBRestRequest object which holds useful information for + * creating a table model + * @param summariesList + * the summary list which contains the data for populating the + * table's rows + * @return the table model which was dynamically generated + */ + public static DefaultTableModel getTableModel(PDBRestRequest request, + Collection summariesList) + { + DefaultTableModel tableModel = new DefaultTableModel(); + + if (request.getAssociatedSequence() != null) + { + tableModel.addColumn("Sequence"); // Create sequence column header if + // exists in the request + } + for (PDBDocField field : request.getWantedFields()) + { + tableModel.addColumn(field.getName()); // Create sequence column header if + // exists in the request + } + + for (PDBResponseSummary res : summariesList) + { + tableModel.addRow(res.getSummaryData()); // Populate table rows with + // summary list + } + + return tableModel; + } + + /** + * Model for a unique response summary + * + */ + public class PDBResponseSummary + { + private String pdbId; + + private String[] summaryRowData; + + private String associatedSequence; + + public PDBResponseSummary(JSONObject pdbJsonDoc, PDBRestRequest request) + { + Collection diplayFields = request.getWantedFields(); + String associatedSeq = request.getAssociatedSequence(); + int colCounter = 0; + summaryRowData = new String[(associatedSeq != null) ? diplayFields + .size() + 1 : diplayFields.size()]; + if (associatedSeq != null) + { + this.associatedSequence = (associatedSeq.length() > 18) ? associatedSeq + .substring(0, 18) : associatedSeq; + summaryRowData[0] = associatedSequence; + colCounter = 1; + } + + for (PDBDocField field : diplayFields) + { + String fieldData = (pdbJsonDoc.get(field.getCode()) == null) ? "" + : pdbJsonDoc + .get(field.getCode()).toString(); + if (field.equals(PDBDocField.PDB_ID)) + { + this.pdbId = fieldData; + summaryRowData[colCounter++] = this.pdbId; + } + else + { + summaryRowData[colCounter++] = fieldData; + } + } + } + + public String getPdbId() + { + return pdbId; + } + + public void setPdbId(String pdbId) + { + this.pdbId = pdbId; + } + + public String[] getSummaryData() + { + return summaryRowData; + } + + public void setSummaryData(String[] summaryData) + { + this.summaryRowData = summaryData; + } + + /** + * Returns a string representation of this object; + */ + @Override + public String toString() + { + StringBuilder summaryFieldValues = new StringBuilder(); + for (String summaryField : summaryRowData) + { + summaryFieldValues.append(summaryField).append("\t"); + } + return summaryFieldValues.toString(); + } + + /** + * Returns hash code value for this object + */ + @Override + public int hashCode() + { + return Objects.hash(this.pdbId, this.toString()); + } + + /** + * Indicates whether some object is equal to this one + */ + @Override + public boolean equals(Object that) + { + if (!(that instanceof PDBResponseSummary)) + { + return false; + } + PDBResponseSummary another = (PDBResponseSummary) that; + return this.toString().equals(another.toString()); + } + + } + +} + diff --git a/src/uk/ac/ebi/picr/model/CrossReference.java b/src/uk/ac/ebi/picr/model/CrossReference.java index aef2ca9..498a47b 100644 --- a/src/uk/ac/ebi/picr/model/CrossReference.java +++ b/src/uk/ac/ebi/picr/model/CrossReference.java @@ -244,15 +244,22 @@ public class CrossReference implements java.io.Serializable private java.lang.Object __equalsCalc = null; + @Override public synchronized boolean equals(java.lang.Object obj) { + if (obj == null) + { + return false; + } if (!(obj instanceof CrossReference)) + { return false; + } CrossReference other = (CrossReference) obj; - if (obj == null) - return false; if (this == obj) + { return true; + } if (__equalsCalc != null) { return (__equalsCalc == obj); @@ -285,6 +292,11 @@ public class CrossReference implements java.io.Serializable private boolean __hashCodeCalc = false; + /** + * hashCode designed to ensure that if two instances satisfy o1.equals(o2) + * then they have the same hashcode. + */ + @Override public synchronized int hashCode() { if (__hashCodeCalc) diff --git a/src/uk/ac/ebi/picr/model/UPEntry.java b/src/uk/ac/ebi/picr/model/UPEntry.java index 0390d48..c94bf15 100644 --- a/src/uk/ac/ebi/picr/model/UPEntry.java +++ b/src/uk/ac/ebi/picr/model/UPEntry.java @@ -198,15 +198,22 @@ public class UPEntry implements java.io.Serializable private java.lang.Object __equalsCalc = null; + @Override public synchronized boolean equals(java.lang.Object obj) { + if (obj == null) + { + return false; + } if (!(obj instanceof UPEntry)) + { return false; + } UPEntry other = (UPEntry) obj; - if (obj == null) - return false; if (this == obj) + { return true; + } if (__equalsCalc != null) { return (__equalsCalc == obj); @@ -236,6 +243,7 @@ public class UPEntry implements java.io.Serializable private boolean __hashCodeCalc = false; + @Override public synchronized int hashCode() { if (__hashCodeCalc) diff --git a/src/uk/ac/ebi/www/Data.java b/src/uk/ac/ebi/www/Data.java index b12de70..2020fc9 100755 --- a/src/uk/ac/ebi/www/Data.java +++ b/src/uk/ac/ebi/www/Data.java @@ -52,17 +52,18 @@ public class Data implements java.io.Serializable private java.lang.Object __equalsCalc = null; + @Override public synchronized boolean equals(java.lang.Object obj) { - if (!(obj instanceof Data)) + if (obj == null) { return false; } - Data other = (Data) obj; - if (obj == null) + if (!(obj instanceof Data)) { return false; } + Data other = (Data) obj; if (this == obj) { return true; @@ -84,6 +85,7 @@ public class Data implements java.io.Serializable private boolean __hashCodeCalc = false; + @Override public synchronized int hashCode() { if (__hashCodeCalc) diff --git a/src/uk/ac/ebi/www/InputParams.java b/src/uk/ac/ebi/www/InputParams.java index 189c7f6..fe1c70c 100755 --- a/src/uk/ac/ebi/www/InputParams.java +++ b/src/uk/ac/ebi/www/InputParams.java @@ -220,17 +220,18 @@ public class InputParams implements java.io.Serializable private java.lang.Object __equalsCalc = null; + @Override public synchronized boolean equals(java.lang.Object obj) { - if (!(obj instanceof InputParams)) + if (obj == null) { return false; } - InputParams other = (InputParams) obj; - if (obj == null) + if (!(obj instanceof InputParams)) { return false; } + InputParams other = (InputParams) obj; if (this == obj) { return true; @@ -274,6 +275,7 @@ public class InputParams implements java.io.Serializable private boolean __hashCodeCalc = false; + @Override public synchronized int hashCode() { if (__hashCodeCalc) diff --git a/src/uk/ac/ebi/www/WSFile.java b/src/uk/ac/ebi/www/WSFile.java index 9199353..210de76 100755 --- a/src/uk/ac/ebi/www/WSFile.java +++ b/src/uk/ac/ebi/www/WSFile.java @@ -52,17 +52,18 @@ public class WSFile implements java.io.Serializable private java.lang.Object __equalsCalc = null; + @Override public synchronized boolean equals(java.lang.Object obj) { - if (!(obj instanceof WSFile)) + if (obj == null) { return false; } - WSFile other = (WSFile) obj; - if (obj == null) + if (!(obj instanceof WSFile)) { return false; } + WSFile other = (WSFile) obj; if (this == obj) { return true; @@ -84,6 +85,7 @@ public class WSFile implements java.io.Serializable private boolean __hashCodeCalc = false; + @Override public synchronized int hashCode() { if (__hashCodeCalc) diff --git a/src/vamsas/objects/simple/Alignment.java b/src/vamsas/objects/simple/Alignment.java index 9bff9cf..9d47b6a 100755 --- a/src/vamsas/objects/simple/Alignment.java +++ b/src/vamsas/objects/simple/Alignment.java @@ -103,15 +103,22 @@ public class Alignment extends vamsas.objects.simple.Object implements private java.lang.Object __equalsCalc = null; + @Override public synchronized boolean equals(java.lang.Object obj) { + if (obj == null) + { + return false; + } if (!(obj instanceof Alignment)) + { return false; + } Alignment other = (Alignment) obj; - if (obj == null) - return false; if (this == obj) + { return true; + } if (__equalsCalc != null) { return (__equalsCalc == obj); @@ -131,6 +138,7 @@ public class Alignment extends vamsas.objects.simple.Object implements private boolean __hashCodeCalc = false; + @Override public synchronized int hashCode() { if (__hashCodeCalc) diff --git a/src/vamsas/objects/simple/JpredResult.java b/src/vamsas/objects/simple/JpredResult.java index 9db8cfe..cc7cc67 100755 --- a/src/vamsas/objects/simple/JpredResult.java +++ b/src/vamsas/objects/simple/JpredResult.java @@ -79,17 +79,18 @@ public class JpredResult extends vamsas.objects.simple.Result implements private java.lang.Object __equalsCalc = null; + @Override public synchronized boolean equals(java.lang.Object obj) { - if (!(obj instanceof JpredResult)) + if (obj == null) { return false; } - JpredResult other = (JpredResult) obj; - if (obj == null) + if (!(obj instanceof JpredResult)) { return false; } + JpredResult other = (JpredResult) obj; if (this == obj) { return true; @@ -111,6 +112,7 @@ public class JpredResult extends vamsas.objects.simple.Result implements private boolean __hashCodeCalc = false; + @Override public synchronized int hashCode() { if (__hashCodeCalc) diff --git a/src/vamsas/objects/simple/MsaResult.java b/src/vamsas/objects/simple/MsaResult.java index 30a5414..49fa4a7 100755 --- a/src/vamsas/objects/simple/MsaResult.java +++ b/src/vamsas/objects/simple/MsaResult.java @@ -58,20 +58,20 @@ public class MsaResult extends vamsas.objects.simple.Result implements this.msa = msa; } + @Override public synchronized boolean equals(java.lang.Object obj) { - if (!(obj instanceof MsaResult)) + if (obj == null) { return false; } - - MsaResult other = (MsaResult) obj; - - if (obj == null) + if (!(obj instanceof MsaResult)) { return false; } + MsaResult other = (MsaResult) obj; + if (this == obj) { return true; @@ -93,6 +93,7 @@ public class MsaResult extends vamsas.objects.simple.Result implements return _equals; } + @Override public synchronized int hashCode() { if (__hashCodeCalc) diff --git a/src/vamsas/objects/simple/Msfalignment.java b/src/vamsas/objects/simple/Msfalignment.java index 573eb96..90370f0 100755 --- a/src/vamsas/objects/simple/Msfalignment.java +++ b/src/vamsas/objects/simple/Msfalignment.java @@ -78,17 +78,18 @@ public class Msfalignment implements java.io.Serializable private java.lang.Object __equalsCalc = null; + @Override public synchronized boolean equals(java.lang.Object obj) { - if (!(obj instanceof Msfalignment)) + if (obj == null) { return false; } - Msfalignment other = (Msfalignment) obj; - if (obj == null) + if (!(obj instanceof Msfalignment)) { return false; } + Msfalignment other = (Msfalignment) obj; if (this == obj) { return true; @@ -110,6 +111,7 @@ public class Msfalignment implements java.io.Serializable private boolean __hashCodeCalc = false; + @Override public synchronized int hashCode() { if (__hashCodeCalc) diff --git a/src/vamsas/objects/simple/Object.java b/src/vamsas/objects/simple/Object.java index 23eedec..7e79e6a 100755 --- a/src/vamsas/objects/simple/Object.java +++ b/src/vamsas/objects/simple/Object.java @@ -29,15 +29,21 @@ public abstract class Object implements java.io.Serializable private java.lang.Object __equalsCalc = null; + @Override public synchronized boolean equals(java.lang.Object obj) { - if (!(obj instanceof Object)) - return false; - Object other = (Object) obj; if (obj == null) + { + return false; + } + if (!(obj instanceof Object)) + { return false; + } if (this == obj) + { return true; + } if (__equalsCalc != null) { return (__equalsCalc == obj); @@ -51,6 +57,7 @@ public abstract class Object implements java.io.Serializable private boolean __hashCodeCalc = false; + @Override public synchronized int hashCode() { if (__hashCodeCalc) diff --git a/src/vamsas/objects/simple/Result.java b/src/vamsas/objects/simple/Result.java index 18293f5..87f0a48 100755 --- a/src/vamsas/objects/simple/Result.java +++ b/src/vamsas/objects/simple/Result.java @@ -288,15 +288,22 @@ public class Result implements java.io.Serializable private java.lang.Object __equalsCalc = null; + @Override public synchronized boolean equals(java.lang.Object obj) { + if (obj == null) + { + return false; + } if (!(obj instanceof Result)) + { return false; + } Result other = (Result) obj; - if (obj == null) - return false; if (this == obj) + { return true; + } if (__equalsCalc != null) { return (__equalsCalc == obj); @@ -322,6 +329,7 @@ public class Result implements java.io.Serializable private boolean __hashCodeCalc = false; + @Override public synchronized int hashCode() { if (__hashCodeCalc) diff --git a/src/vamsas/objects/simple/Secstructpred.java b/src/vamsas/objects/simple/Secstructpred.java index 77fdd34..349c21e 100755 --- a/src/vamsas/objects/simple/Secstructpred.java +++ b/src/vamsas/objects/simple/Secstructpred.java @@ -57,15 +57,15 @@ public class Secstructpred implements java.io.Serializable public synchronized boolean equals(java.lang.Object obj) { - if (!(obj instanceof Secstructpred)) + if (obj == null) { return false; } - Secstructpred other = (Secstructpred) obj; - if (obj == null) + if (!(obj instanceof Secstructpred)) { return false; } + Secstructpred other = (Secstructpred) obj; if (this == obj) { return true; diff --git a/src/vamsas/objects/simple/SeqSearchResult.java b/src/vamsas/objects/simple/SeqSearchResult.java index 98d1d21..8ef8f7c 100644 --- a/src/vamsas/objects/simple/SeqSearchResult.java +++ b/src/vamsas/objects/simple/SeqSearchResult.java @@ -127,15 +127,22 @@ public class SeqSearchResult extends vamsas.objects.simple.Result implements private java.lang.Object __equalsCalc = null; + @Override public synchronized boolean equals(java.lang.Object obj) { + if (obj == null) + { + return false; + } if (!(obj instanceof SeqSearchResult)) + { return false; + } SeqSearchResult other = (SeqSearchResult) obj; - if (obj == null) - return false; if (this == obj) + { return true; + } if (__equalsCalc != null) { return (__equalsCalc == obj); @@ -157,6 +164,7 @@ public class SeqSearchResult extends vamsas.objects.simple.Result implements private boolean __hashCodeCalc = false; + @Override public synchronized int hashCode() { if (__hashCodeCalc) diff --git a/src/vamsas/objects/simple/Sequence.java b/src/vamsas/objects/simple/Sequence.java index 28dc9eb..8eb7208 100755 --- a/src/vamsas/objects/simple/Sequence.java +++ b/src/vamsas/objects/simple/Sequence.java @@ -78,15 +78,22 @@ public class Sequence implements java.io.Serializable private java.lang.Object __equalsCalc = null; + @Override public synchronized boolean equals(java.lang.Object obj) { + if (obj == null) + { + return false; + } if (!(obj instanceof Sequence)) + { return false; + } Sequence other = (Sequence) obj; - if (obj == null) - return false; if (this == obj) + { return true; + } if (__equalsCalc != null) { return (__equalsCalc == obj); @@ -104,6 +111,7 @@ public class Sequence implements java.io.Serializable private boolean __hashCodeCalc = false; + @Override public synchronized int hashCode() { if (__hashCodeCalc) diff --git a/src/vamsas/objects/simple/SequenceSet.java b/src/vamsas/objects/simple/SequenceSet.java index 2c43f96..d5a269b 100755 --- a/src/vamsas/objects/simple/SequenceSet.java +++ b/src/vamsas/objects/simple/SequenceSet.java @@ -55,15 +55,22 @@ public class SequenceSet implements java.io.Serializable private java.lang.Object __equalsCalc = null; + @Override public synchronized boolean equals(java.lang.Object obj) { + if (obj == null) + { + return false; + } if (!(obj instanceof SequenceSet)) + { return false; + } SequenceSet other = (SequenceSet) obj; - if (obj == null) - return false; if (this == obj) + { return true; + } if (__equalsCalc != null) { return (__equalsCalc == obj); @@ -78,6 +85,7 @@ public class SequenceSet implements java.io.Serializable private boolean __hashCodeCalc = false; + @Override public synchronized int hashCode() { if (__hashCodeCalc) diff --git a/src/vamsas/objects/simple/WsJobId.java b/src/vamsas/objects/simple/WsJobId.java index 3419899..eb04dcf 100755 --- a/src/vamsas/objects/simple/WsJobId.java +++ b/src/vamsas/objects/simple/WsJobId.java @@ -78,15 +78,22 @@ public class WsJobId implements java.io.Serializable private java.lang.Object __equalsCalc = null; + @Override public synchronized boolean equals(java.lang.Object obj) { + if (obj == null) + { + return false; + } if (!(obj instanceof WsJobId)) + { return false; + } WsJobId other = (WsJobId) obj; - if (obj == null) - return false; if (this == obj) + { return true; + } if (__equalsCalc != null) { return (__equalsCalc == obj); @@ -103,6 +110,7 @@ public class WsJobId implements java.io.Serializable private boolean __hashCodeCalc = false; + @Override public synchronized int hashCode() { if (__hashCodeCalc) diff --git a/test/jalview/analysis/AAFrequencyTest.java b/test/jalview/analysis/AAFrequencyTest.java new file mode 100644 index 0000000..788e742 --- /dev/null +++ b/test/jalview/analysis/AAFrequencyTest.java @@ -0,0 +1,134 @@ + +package jalview.analysis; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; + +import java.util.Hashtable; + +import org.junit.Test; + +public class AAFrequencyTest +{ + private static final String C = AAFrequency.MAXCOUNT; + + private static final String R = AAFrequency.MAXRESIDUE; + + private static final String G = AAFrequency.PID_GAPS; + + private static final String N = AAFrequency.PID_NOGAPS; + + private static final String P = AAFrequency.PROFILE; + + @Test + public void testCalculate_noProfile() + { + SequenceI seq1 = new Sequence("Seq1", "CAGT"); + SequenceI seq2 = new Sequence("Seq2", "CACT"); + SequenceI seq3 = new Sequence("Seq3", "C--G"); + SequenceI seq4 = new Sequence("Seq4", "CA-t"); + SequenceI[] seqs = new SequenceI[] + { seq1, seq2, seq3, seq4 }; + Hashtable[] result = new Hashtable[seq1.getLength()]; + + AAFrequency.calculate(seqs, 0, seq1.getLength(), result, false); + + // col 0 is 100% C + Hashtable col = result[0]; + assertEquals(100f, (Float) col.get(G), 0.0001f); + assertEquals(100f, (Float) col.get(N), 0.0001f); + assertEquals(4, col.get(C)); + assertEquals("C", col.get(R)); + assertNull(col.get(P)); + + // col 1 is 75% A + col = result[1]; + assertEquals(75f, (Float) col.get(G), 0.0001f); + assertEquals(100f, (Float) col.get(N), 0.0001f); + assertEquals(3, col.get(C)); + assertEquals("A", col.get(R)); + + // col 2 is 50% G 50% C or 25/25 counting gaps + col = result[2]; + assertEquals(25f, (Float) col.get(G), 0.0001f); + assertEquals(50f, (Float) col.get(N), 0.0001f); + assertEquals(1, col.get(C)); + assertEquals("CG", col.get(R)); + + // col 3 is 75% T 25% G + col = result[3]; + assertEquals(75f, (Float) col.get(G), 0.0001f); + assertEquals(75f, (Float) col.get(N), 0.0001f); + assertEquals(3, col.get(C)); + assertEquals("T", col.get(R)); + } + + @Test + public void testCalculate_withProfile() + { + SequenceI seq1 = new Sequence("Seq1", "CAGT"); + SequenceI seq2 = new Sequence("Seq2", "CACT"); + SequenceI seq3 = new Sequence("Seq3", "C--G"); + SequenceI seq4 = new Sequence("Seq4", "CA-t"); + SequenceI[] seqs = new SequenceI[] + { seq1, seq2, seq3, seq4 }; + Hashtable[] result = new Hashtable[seq1.getLength()]; + + AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true); + int[][] profile = (int[][]) result[0].get(P); + assertEquals(4, profile[0]['C']); + assertEquals(4, profile[1][0]); // no of seqs + assertEquals(4, profile[1][1]); // nongapped in column + + profile = (int[][]) result[1].get(P); + assertEquals(3, profile[0]['A']); + assertEquals(4, profile[1][0]); + assertEquals(3, profile[1][1]); + + profile = (int[][]) result[2].get(P); + assertEquals(1, profile[0]['G']); + assertEquals(1, profile[0]['C']); + assertEquals(4, profile[1][0]); + assertEquals(2, profile[1][1]); + + profile = (int[][]) result[3].get(P); + assertEquals(3, profile[0]['T']); + assertEquals(1, profile[0]['G']); + assertEquals(4, profile[1][0]); + assertEquals(4, profile[1][1]); + } + + @Test + public void testCalculate_withProfileTiming() + { + SequenceI seq1 = new Sequence("Seq1", "CAGT"); + SequenceI seq2 = new Sequence("Seq2", "CACT"); + SequenceI seq3 = new Sequence("Seq3", "C--G"); + SequenceI seq4 = new Sequence("Seq4", "CA-t"); + SequenceI[] seqs = new SequenceI[] + { seq1, seq2, seq3, seq4 }; + Hashtable[] result = new Hashtable[seq1.getLength()]; + + // ensure class loaded and initialized + AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true); + int reps = 100000; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + { + AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true); + } + System.out.println(System.currentTimeMillis() - start); + } + + @Test + public void testGetPercentageFormat() + { + assertNull(AAFrequency.getPercentageFormat(0)); + assertNull(AAFrequency.getPercentageFormat(99)); + assertEquals("%3.1f", AAFrequency.getPercentageFormat(100).toString()); + assertEquals("%3.1f", AAFrequency.getPercentageFormat(999).toString()); + assertEquals("%3.2f", AAFrequency.getPercentageFormat(1000).toString()); + assertEquals("%3.2f", AAFrequency.getPercentageFormat(9999).toString()); + } +} diff --git a/test/jalview/analysis/AlignmentUtilsTests.java b/test/jalview/analysis/AlignmentUtilsTests.java index bba21c3..bc6a137 100644 --- a/test/jalview/analysis/AlignmentUtilsTests.java +++ b/test/jalview/analysis/AlignmentUtilsTests.java @@ -20,19 +20,70 @@ */ package jalview.analysis; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; + import org.junit.Test; +import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; +import jalview.datamodel.Annotation; +import jalview.datamodel.DBRefEntry; +import jalview.datamodel.Mapping; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; import jalview.io.AppletFormatAdapter; +import jalview.io.FormatAdapter; +import jalview.util.MapList; public class AlignmentUtilsTests { + // @formatter:off + private static final String TEST_DATA = + "# STOCKHOLM 1.0\n" + + "#=GS D.melanogaster.1 AC AY119185.1/838-902\n" + + "#=GS D.melanogaster.2 AC AC092237.1/57223-57161\n" + + "#=GS D.melanogaster.3 AC AY060611.1/560-627\n" + + "D.melanogaster.1 G.AGCC.CU...AUGAUCGA\n" + + "#=GR D.melanogaster.1 SS ................((((\n" + + "D.melanogaster.2 C.AUUCAACU.UAUGAGGAU\n" + + "#=GR D.melanogaster.2 SS ................((((\n" + + "D.melanogaster.3 G.UGGCGCU..UAUGACGCA\n" + + "#=GR D.melanogaster.3 SS (.(((...(....(((((((\n" + + "//"; + + private static final String AA_SEQS_1 = + ">Seq1Name\n" + + "K-QY--L\n" + + ">Seq2Name\n" + + "-R-FP-W-\n"; + + private static final String CDNA_SEQS_1 = + ">Seq1Name\n" + + "AC-GG--CUC-CAA-CT\n" + + ">Seq2Name\n" + + "-CG-TTA--ACG---AAGT\n"; + + private static final String CDNA_SEQS_2 = + ">Seq1Name\n" + + "GCTCGUCGTACT\n" + + ">Seq2Name\n" + + "GGGTCAGGCAGT\n"; + // @formatter:on + public static Sequence ts=new Sequence("short","ASDASDASDASDASDASDASDASDASDASDASDASDASD"); + @Test public void testExpandFlanks() { @@ -55,6 +106,708 @@ public class AlignmentUtilsTests assertTrue("Flanking sequence not the same as original dataset sequence.\n"+ung+"\n"+sq.getDatasetSequence().getSequenceAsString(),ung.equalsIgnoreCase(sq.getDatasetSequence().getSequenceAsString())); } } + } } + + /** + * Test method that returns a map of lists of sequences by sequence name. + * + * @throws IOException + */ + @Test + public void testGetSequencesByName() throws IOException + { + final String data = ">Seq1Name\nKQYL\n" + ">Seq2Name\nRFPW\n" + + ">Seq1Name\nABCD\n"; + AlignmentI al = loadAlignment(data, "FASTA"); + Map> map = AlignmentUtils + .getSequencesByName(al); + assertEquals(2, map.keySet().size()); + assertEquals(2, map.get("Seq1Name").size()); + assertEquals("KQYL", map.get("Seq1Name").get(0).getSequenceAsString()); + assertEquals("ABCD", map.get("Seq1Name").get(1).getSequenceAsString()); + assertEquals(1, map.get("Seq2Name").size()); + assertEquals("RFPW", map.get("Seq2Name").get(0).getSequenceAsString()); + } + /** + * Helper method to load an alignment and ensure dataset sequences are set up. + * + * @param data + * @param format TODO + * @return + * @throws IOException + */ + protected AlignmentI loadAlignment(final String data, String format) throws IOException + { + Alignment a = new FormatAdapter().readFile(data, + AppletFormatAdapter.PASTE, format); + a.setDataset(null); + return a; + } + + /** + * Test mapping of protein to cDNA, for the case where we have no sequence + * cross-references, so mappings are made first-served 1-1 where sequences + * translate. + * + * @throws IOException + */ + @Test + public void testMapProteinToCdna_noXrefs() throws IOException + { + List protseqs = new ArrayList(); + protseqs.add(new Sequence("UNIPROT|V12345", "EIQ")); + protseqs.add(new Sequence("UNIPROT|V12346", "EIQ")); + protseqs.add(new Sequence("UNIPROT|V12347", "SAR")); + AlignmentI protein = new Alignment(protseqs.toArray(new SequenceI[3])); + protein.setDataset(null); + + List dnaseqs = new ArrayList(); + dnaseqs.add(new Sequence("EMBL|A11111", "TCAGCACGC")); // = SAR + dnaseqs.add(new Sequence("EMBL|A22222", "GAGATACAA")); // = EIQ + dnaseqs.add(new Sequence("EMBL|A33333", "GAAATCCAG")); // = EIQ + dnaseqs.add(new Sequence("EMBL|A44444", "GAAATTCAG")); // = EIQ + AlignmentI cdna = new Alignment(dnaseqs.toArray(new SequenceI[4])); + cdna.setDataset(null); + + assertTrue(AlignmentUtils.mapProteinToCdna(protein, cdna)); + + // 3 mappings made, each from 1 to 1 sequence + assertEquals(3, protein.getCodonFrames().size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(0)).size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(1)).size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(2)).size()); + + // V12345 mapped to A22222 + AlignedCodonFrame acf = protein.getCodonFrame( + protein.getSequenceAt(0)).get(0); + assertEquals(1, acf.getdnaSeqs().length); + assertEquals(cdna.getSequenceAt(1).getDatasetSequence(), + acf.getdnaSeqs()[0]); + Mapping[] protMappings = acf.getProtMappings(); + assertEquals(1, protMappings.length); + MapList mapList = protMappings[0].getMap(); + assertEquals(3, mapList.getFromRatio()); + assertEquals(1, mapList.getToRatio()); + assertTrue(Arrays.equals(new int[] + { 1, 9 }, mapList.getFromRanges().get(0))); + assertEquals(1, mapList.getFromRanges().size()); + assertTrue(Arrays.equals(new int[] + { 1, 3 }, mapList.getToRanges().get(0))); + assertEquals(1, mapList.getToRanges().size()); + + // V12346 mapped to A33333 + acf = protein.getCodonFrame(protein.getSequenceAt(1)).get(0); + assertEquals(1, acf.getdnaSeqs().length); + assertEquals(cdna.getSequenceAt(2).getDatasetSequence(), + acf.getdnaSeqs()[0]); + + // V12347 mapped to A11111 + acf = protein.getCodonFrame(protein.getSequenceAt(2)).get(0); + assertEquals(1, acf.getdnaSeqs().length); + assertEquals(cdna.getSequenceAt(0).getDatasetSequence(), + acf.getdnaSeqs()[0]); + + // no mapping involving the 'extra' A44444 + assertTrue(protein.getCodonFrame(cdna.getSequenceAt(3)).isEmpty()); + } + + /** + * Test for the alignSequenceAs method that takes two sequences and a mapping. + */ + @Test + public void testAlignSequenceAs_withMapping_noIntrons() + { + MapList map = new MapList(new int[] + { 1, 6 }, new int[] + { 1, 2 }, 3, 1); + + /* + * No existing gaps in dna: + */ + checkAlignSequenceAs("GGGAAA", "-A-L-", false, false, map, + "---GGG---AAA"); + + /* + * Now introduce gaps in dna but ignore them when realigning. + */ + checkAlignSequenceAs("-G-G-G-A-A-A-", "-A-L-", false, false, map, + "---GGG---AAA"); + + /* + * Now include gaps in dna when realigning. First retaining 'mapped' gaps + * only, i.e. those within the exon region. + */ + checkAlignSequenceAs("-G-G--G-A--A-A-", "-A-L-", true, false, map, + "---G-G--G---A--A-A"); + + /* + * Include all gaps in dna when realigning (within and without the exon + * region). The leading gap, and the gaps between codons, are subsumed by + * the protein alignment gap. + */ + checkAlignSequenceAs("-G-GG--AA-A-", "-A-L-", true, true, map, + "---G-GG---AA-A-"); + + /* + * Include only unmapped gaps in dna when realigning (outside the exon + * region). The leading gap, and the gaps between codons, are subsumed by + * the protein alignment gap. + */ + checkAlignSequenceAs("-G-GG--AA-A-", "-A-L-", false, true, map, + "---GGG---AAA-"); + } + + /** + * Test for the alignSequenceAs method that takes two sequences and a mapping. + */ + @Test + public void testAlignSequenceAs_withMapping_withIntrons() + { + /* + * Exons at codon 2 (AAA) and 4 (TTT) + */ + MapList map = new MapList(new int[] + { 4, 6, 10, 12 }, new int[] + { 1, 2 }, 3, 1); + + /* + * Simple case: no gaps in dna + */ + checkAlignSequenceAs("GGGAAACCCTTTGGG", "--A-L-", false, false, map, + "GGG---AAACCCTTTGGG"); + + /* + * Add gaps to dna - but ignore when realigning. + */ + checkAlignSequenceAs("-G-G-G--A--A---AC-CC-T-TT-GG-G-", "--A-L-", + false, false, map, "GGG---AAACCCTTTGGG"); + + /* + * Add gaps to dna - include within exons only when realigning. + */ + checkAlignSequenceAs("-G-G-G--A--A---A-C-CC-T-TT-GG-G-", "--A-L-", + true, false, map, "GGG---A--A---ACCCT-TTGGG"); + + /* + * Include gaps outside exons only when realigning. + */ + checkAlignSequenceAs("-G-G-G--A--A---A-C-CC-T-TT-GG-G-", "--A-L-", + false, true, map, "-G-G-GAAAC-CCTTT-GG-G-"); + + /* + * Include gaps following first intron if we are 'preserving mapped gaps' + */ + checkAlignSequenceAs("-G-G-G--A--A---A-C-CC-T-TT-GG-G-", "--A-L-", + true, true, map, "-G-G-G--A--A---A-C-CC-T-TT-GG-G-"); + + /* + * Include all gaps in dna when realigning. + */ + checkAlignSequenceAs("-G-G-G--A--A---A-C-CC-T-TT-GG-G-", "--A-L-", + true, true, map, "-G-G-G--A--A---A-C-CC-T-TT-GG-G-"); + } + + /** + * Test for the case where not all of the protein sequence is mapped to cDNA. + */ + @Test + public void testAlignSequenceAs_withMapping_withUnmappedProtein() + { + + /* + * Exons at codon 2 (AAA) and 4 (TTT) mapped to A and P + */ + final MapList map = new MapList(new int[] + { 4, 6, 10, 12 }, new int[] + { 1, 1, 3, 3 }, 3, 1); + + + /* + * Expect alignment does nothing (aborts realignment). Change this test + * first if different behaviour wanted. + */ + checkAlignSequenceAs("GGGAAACCCTTTGGG", "-A-L-P-", false, + false, map, "GGGAAACCCTTTGGG"); + } + + /** + * Helper method that performs and verifies the method under test. + * + * @param dnaSeq + * @param proteinSeq + * @param preserveMappedGaps + * @param preserveUnmappedGaps + * @param map + * @param expected + */ + protected void checkAlignSequenceAs(final String dnaSeq, + final String proteinSeq, final boolean preserveMappedGaps, + final boolean preserveUnmappedGaps, MapList map, + final String expected) + { + SequenceI dna = new Sequence("Seq1", dnaSeq); + dna.createDatasetSequence(); + SequenceI protein = new Sequence("Seq1", proteinSeq); + protein.createDatasetSequence(); + AlignedCodonFrame acf = new AlignedCodonFrame(); + acf.addMap(dna.getDatasetSequence(), protein.getDatasetSequence(), map); + + AlignmentUtils.alignSequenceAs(dna, protein, acf, "---", '-', + preserveMappedGaps, preserveUnmappedGaps); + assertEquals(expected, dna.getSequenceAsString()); + } + + /** + * Test for the alignSequenceAs method where we preserve gaps in introns only. + */ + @Test + public void testAlignSequenceAs_keepIntronGapsOnly() + { + + /* + * Intron GGGAAA followed by exon CCCTTT + */ + MapList map = new MapList(new int[] + { 7, 12 }, new int[] + { 1, 2 }, 3, 1); + + checkAlignSequenceAs("GG-G-AA-A-C-CC-T-TT", "AL", + false, true, map, "GG-G-AA-ACCCTTT"); + } + + /** + * Test for the method that generates an aligned translated sequence from one + * mapping. + */ + @Test + public void testGetAlignedTranslation_dnaLikeProtein() + { + // dna alignment will be replaced + SequenceI dna = new Sequence("Seq1", "T-G-CC-A--T-TAC-CAG-"); + dna.createDatasetSequence(); + // protein alignment will be 'applied' to dna + SequenceI protein = new Sequence("Seq1", "-CH-Y--Q-"); + protein.createDatasetSequence(); + MapList map = new MapList(new int[] + { 1, 12 }, new int[] + { 1, 4 }, 3, 1); + AlignedCodonFrame acf = new AlignedCodonFrame(); + acf.addMap(dna.getDatasetSequence(), protein.getDatasetSequence(), map); + + final SequenceI aligned = AlignmentUtils + .getAlignedTranslation(protein, '-', acf); + assertEquals("---TGCCAT---TAC------CAG---", aligned.getSequenceAsString()); + assertSame(aligned.getDatasetSequence(), dna.getDatasetSequence()); + } + + /** + * Test the method that realigns protein to match mapped codon alignment. + */ + @Test + public void testAlignProteinAsDna() + { + // seq1 codons are [1,2,3] [4,5,6] [7,8,9] [10,11,12] + SequenceI dna1 = new Sequence("Seq1", "TGCCATTACCAG-"); + // seq2 codons are [1,3,4] [5,6,7] [8,9,10] [11,12,13] + SequenceI dna2 = new Sequence("Seq2", "T-GCCATTACCAG"); + // seq3 codons are [1,2,3] [4,5,7] [8,9,10] [11,12,13] + SequenceI dna3 = new Sequence("Seq3", "TGCCA-TTACCAG"); + AlignmentI dna = new Alignment(new SequenceI[] + { dna1, dna2, dna3 }); + dna.setDataset(null); + + // protein alignment will be realigned like dna + SequenceI prot1 = new Sequence("Seq1", "CHYQ"); + SequenceI prot2 = new Sequence("Seq2", "CHYQ"); + SequenceI prot3 = new Sequence("Seq3", "CHYQ"); + AlignmentI protein = new Alignment(new SequenceI[] + { prot1, prot2, prot3 }); + protein.setDataset(null); + + MapList map = new MapList(new int[] + { 1, 12 }, new int[] + { 1, 4 }, 3, 1); + AlignedCodonFrame acf = new AlignedCodonFrame(); + acf.addMap(dna1.getDatasetSequence(), prot1.getDatasetSequence(), map); + acf.addMap(dna2.getDatasetSequence(), prot2.getDatasetSequence(), map); + acf.addMap(dna3.getDatasetSequence(), prot3.getDatasetSequence(), map); + protein.setCodonFrames(Collections.singleton(acf)); + + /* + * Translated codon order is [1,2,3] [1,3,4] [4,5,6] [4,5,7] [5,6,7] [7,8,9] + * [8,9,10] [10,11,12] [11,12,13] + */ + AlignmentUtils.alignProteinAsDna(protein, dna); + assertEquals("C-H--Y-Q-", prot1.getSequenceAsString()); + assertEquals("-C--H-Y-Q", prot2.getSequenceAsString()); + assertEquals("C--H--Y-Q", prot3.getSequenceAsString()); + } + + /** + * Test the method that tests whether a CDNA sequence translates to a protein + * sequence + */ + @Test + public void testTranslatesAs() + { + assertTrue(AlignmentUtils.translatesAs("tttcccaaaggg".toCharArray(), 0, + "FPKG".toCharArray())); + // with start codon + assertTrue(AlignmentUtils.translatesAs("atgtttcccaaaggg".toCharArray(), + 3, "FPKG".toCharArray())); + // with stop codon1 + assertTrue(AlignmentUtils.translatesAs("tttcccaaagggtaa".toCharArray(), + 0, "FPKG".toCharArray())); + // with stop codon2 + assertTrue(AlignmentUtils.translatesAs("tttcccaaagggtag".toCharArray(), + 0, "FPKG".toCharArray())); + // with stop codon3 + assertTrue(AlignmentUtils.translatesAs("tttcccaaagggtga".toCharArray(), + 0, "FPKG".toCharArray())); + // with start and stop codon1 + assertTrue(AlignmentUtils.translatesAs( + "atgtttcccaaaggtaa".toCharArray(), 3, "FPKG".toCharArray())); + // with start and stop codon2 + assertTrue(AlignmentUtils.translatesAs( + "atgtttcccaaaggtag".toCharArray(), 3, "FPKG".toCharArray())); + // with start and stop codon3 + assertTrue(AlignmentUtils.translatesAs( + "atgtttcccaaaggtga".toCharArray(), 3, "FPKG".toCharArray())); + + // wrong protein + assertFalse(AlignmentUtils.translatesAs("tttcccaaaggg".toCharArray(), + 0, + "FPMG".toCharArray())); + } + + /** + * Test mapping of protein to cDNA, for cases where the cDNA has start and/or + * stop codons in addition to the protein coding sequence. + * + * @throws IOException + */ + @Test + public void testMapProteinToCdna_withStartAndStopCodons() + throws IOException + { + List protseqs = new ArrayList(); + protseqs.add(new Sequence("UNIPROT|V12345", "EIQ")); + protseqs.add(new Sequence("UNIPROT|V12346", "EIQ")); + protseqs.add(new Sequence("UNIPROT|V12347", "SAR")); + AlignmentI protein = new Alignment(protseqs.toArray(new SequenceI[3])); + protein.setDataset(null); + + List dnaseqs = new ArrayList(); + // start + SAR: + dnaseqs.add(new Sequence("EMBL|A11111", "ATGTCAGCACGC")); + // = EIQ + stop + dnaseqs.add(new Sequence("EMBL|A22222", "GAGATACAATAA")); + // = start +EIQ + stop + dnaseqs.add(new Sequence("EMBL|A33333", "ATGGAAATCCAGTAG")); + dnaseqs.add(new Sequence("EMBL|A44444", "GAAATTCAG")); + AlignmentI cdna = new Alignment(dnaseqs.toArray(new SequenceI[4])); + cdna.setDataset(null); + + assertTrue(AlignmentUtils.mapProteinToCdna(protein, cdna)); + + // 3 mappings made, each from 1 to 1 sequence + assertEquals(3, protein.getCodonFrames().size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(0)).size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(1)).size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(2)).size()); + + // V12345 mapped from A22222 + AlignedCodonFrame acf = protein.getCodonFrame( + protein.getSequenceAt(0)).get(0); + assertEquals(1, acf.getdnaSeqs().length); + assertEquals(cdna.getSequenceAt(1).getDatasetSequence(), + acf.getdnaSeqs()[0]); + Mapping[] protMappings = acf.getProtMappings(); + assertEquals(1, protMappings.length); + MapList mapList = protMappings[0].getMap(); + assertEquals(3, mapList.getFromRatio()); + assertEquals(1, mapList.getToRatio()); + assertTrue(Arrays.equals(new int[] + { 1, 9 }, mapList.getFromRanges().get(0))); + assertEquals(1, mapList.getFromRanges().size()); + assertTrue(Arrays.equals(new int[] + { 1, 3 }, mapList.getToRanges().get(0))); + assertEquals(1, mapList.getToRanges().size()); + + // V12346 mapped from A33333 starting position 4 + acf = protein.getCodonFrame(protein.getSequenceAt(1)).get(0); + assertEquals(1, acf.getdnaSeqs().length); + assertEquals(cdna.getSequenceAt(2).getDatasetSequence(), + acf.getdnaSeqs()[0]); + protMappings = acf.getProtMappings(); + assertEquals(1, protMappings.length); + mapList = protMappings[0].getMap(); + assertEquals(3, mapList.getFromRatio()); + assertEquals(1, mapList.getToRatio()); + assertTrue(Arrays.equals(new int[] + { 4, 12 }, mapList.getFromRanges().get(0))); + assertEquals(1, mapList.getFromRanges().size()); + assertTrue(Arrays.equals(new int[] + { 1, 3 }, mapList.getToRanges().get(0))); + assertEquals(1, mapList.getToRanges().size()); + + // V12347 mapped to A11111 starting position 4 + acf = protein.getCodonFrame(protein.getSequenceAt(2)).get(0); + assertEquals(1, acf.getdnaSeqs().length); + assertEquals(cdna.getSequenceAt(0).getDatasetSequence(), + acf.getdnaSeqs()[0]); + protMappings = acf.getProtMappings(); + assertEquals(1, protMappings.length); + mapList = protMappings[0].getMap(); + assertEquals(3, mapList.getFromRatio()); + assertEquals(1, mapList.getToRatio()); + assertTrue(Arrays.equals(new int[] + { 4, 12 }, mapList.getFromRanges().get(0))); + assertEquals(1, mapList.getFromRanges().size()); + assertTrue(Arrays.equals(new int[] + { 1, 3 }, mapList.getToRanges().get(0))); + assertEquals(1, mapList.getToRanges().size()); + + // no mapping involving the 'extra' A44444 + assertTrue(protein.getCodonFrame(cdna.getSequenceAt(3)).isEmpty()); + } + + /** + * Test mapping of protein to cDNA, for the case where we have some sequence + * cross-references. Verify that 1-to-many mappings are made where + * cross-references exist and sequences are mappable. + * + * @throws IOException + */ + @Test + public void testMapProteinToCdna_withXrefs() throws IOException + { + List protseqs = new ArrayList(); + protseqs.add(new Sequence("UNIPROT|V12345", "EIQ")); + protseqs.add(new Sequence("UNIPROT|V12346", "EIQ")); + protseqs.add(new Sequence("UNIPROT|V12347", "SAR")); + AlignmentI protein = new Alignment(protseqs.toArray(new SequenceI[3])); + protein.setDataset(null); + + List dnaseqs = new ArrayList(); + dnaseqs.add(new Sequence("EMBL|A11111", "TCAGCACGC")); // = SAR + dnaseqs.add(new Sequence("EMBL|A22222", "ATGGAGATACAA")); // = start + EIQ + dnaseqs.add(new Sequence("EMBL|A33333", "GAAATCCAG")); // = EIQ + dnaseqs.add(new Sequence("EMBL|A44444", "GAAATTCAG")); // = EIQ + dnaseqs.add(new Sequence("EMBL|A55555", "GAGATTCAG")); // = EIQ + AlignmentI cdna = new Alignment(dnaseqs.toArray(new SequenceI[5])); + cdna.setDataset(null); + + // Xref A22222 to V12345 (should get mapped) + dnaseqs.get(1).addDBRef(new DBRefEntry("UNIPROT", "1", "V12345")); + // Xref V12345 to A44444 (should get mapped) + protseqs.get(0).addDBRef(new DBRefEntry("EMBL", "1", "A44444")); + // Xref A33333 to V12347 (sequence mismatch - should not get mapped) + dnaseqs.get(2).addDBRef(new DBRefEntry("UNIPROT", "1", "V12347")); + // as V12345 is mapped to A22222 and A44444, this leaves V12346 unmapped. + // it should get paired up with the unmapped A33333 + // A11111 should be mapped to V12347 + // A55555 is spare and has no xref so is not mapped + + assertTrue(AlignmentUtils.mapProteinToCdna(protein, cdna)); + + // 4 protein mappings made for 3 proteins, 2 to V12345, 1 each to V12346/7 + assertEquals(3, protein.getCodonFrames().size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(0)).size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(1)).size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(2)).size()); + + // one mapping for each of the first 4 cDNA sequences + assertEquals(1, protein.getCodonFrame(cdna.getSequenceAt(0)).size()); + assertEquals(1, protein.getCodonFrame(cdna.getSequenceAt(1)).size()); + assertEquals(1, protein.getCodonFrame(cdna.getSequenceAt(2)).size()); + assertEquals(1, protein.getCodonFrame(cdna.getSequenceAt(3)).size()); + + // V12345 mapped to A22222 and A44444 + AlignedCodonFrame acf = protein.getCodonFrame( + protein.getSequenceAt(0)).get(0); + assertEquals(2, acf.getdnaSeqs().length); + assertEquals(cdna.getSequenceAt(1).getDatasetSequence(), + acf.getdnaSeqs()[0]); + assertEquals(cdna.getSequenceAt(3).getDatasetSequence(), + acf.getdnaSeqs()[1]); + + // V12346 mapped to A33333 + acf = protein.getCodonFrame(protein.getSequenceAt(1)).get(0); + assertEquals(1, acf.getdnaSeqs().length); + assertEquals(cdna.getSequenceAt(2).getDatasetSequence(), + acf.getdnaSeqs()[0]); + + // V12347 mapped to A11111 + acf = protein.getCodonFrame(protein.getSequenceAt(2)).get(0); + assertEquals(1, acf.getdnaSeqs().length); + assertEquals(cdna.getSequenceAt(0).getDatasetSequence(), + acf.getdnaSeqs()[0]); + + // no mapping involving the 'extra' A55555 + assertTrue(protein.getCodonFrame(cdna.getSequenceAt(4)).isEmpty()); + } + + /** + * Test mapping of protein to cDNA, for the case where we have some sequence + * cross-references. Verify that once we have made an xref mapping we don't + * also map un-xrefd sequeces. + * + * @throws IOException + */ + @Test + public void testMapProteinToCdna_prioritiseXrefs() throws IOException + { + List protseqs = new ArrayList(); + protseqs.add(new Sequence("UNIPROT|V12345", "EIQ")); + protseqs.add(new Sequence("UNIPROT|V12346", "EIQ")); + AlignmentI protein = new Alignment( + protseqs.toArray(new SequenceI[protseqs.size()])); + protein.setDataset(null); + + List dnaseqs = new ArrayList(); + dnaseqs.add(new Sequence("EMBL|A11111", "GAAATCCAG")); // = EIQ + dnaseqs.add(new Sequence("EMBL|A22222", "GAAATTCAG")); // = EIQ + AlignmentI cdna = new Alignment(dnaseqs.toArray(new SequenceI[dnaseqs + .size()])); + cdna.setDataset(null); + + // Xref A22222 to V12345 (should get mapped) + // A11111 should then be mapped to the unmapped V12346 + dnaseqs.get(1).addDBRef(new DBRefEntry("UNIPROT", "1", "V12345")); + + assertTrue(AlignmentUtils.mapProteinToCdna(protein, cdna)); + + // 2 protein mappings made + assertEquals(2, protein.getCodonFrames().size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(0)).size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(1)).size()); + + // one mapping for each of the cDNA sequences + assertEquals(1, protein.getCodonFrame(cdna.getSequenceAt(0)).size()); + assertEquals(1, protein.getCodonFrame(cdna.getSequenceAt(1)).size()); + + // V12345 mapped to A22222 + AlignedCodonFrame acf = protein.getCodonFrame(protein.getSequenceAt(0)) + .get(0); + assertEquals(1, acf.getdnaSeqs().length); + assertEquals(cdna.getSequenceAt(1).getDatasetSequence(), + acf.getdnaSeqs()[0]); + + // V12346 mapped to A11111 + acf = protein.getCodonFrame(protein.getSequenceAt(1)).get(0); + assertEquals(1, acf.getdnaSeqs().length); + assertEquals(cdna.getSequenceAt(0).getDatasetSequence(), + acf.getdnaSeqs()[0]); + } + + /** + * Test the method that shows or hides sequence annotations by type(s) and + * selection group. + */ + @Test + public void testShowOrHideSequenceAnnotations() + { + SequenceI seq1 = new Sequence("Seq1", "AAA"); + SequenceI seq2 = new Sequence("Seq2", "BBB"); + SequenceI seq3 = new Sequence("Seq3", "CCC"); + Annotation[] anns = new Annotation[] + { new Annotation(2f) }; + AlignmentAnnotation ann1 = new AlignmentAnnotation("Structure", "ann1", + anns); + ann1.setSequenceRef(seq1); + AlignmentAnnotation ann2 = new AlignmentAnnotation("Structure", "ann2", + anns); + ann2.setSequenceRef(seq2); + AlignmentAnnotation ann3 = new AlignmentAnnotation("Structure", "ann3", + anns); + AlignmentAnnotation ann4 = new AlignmentAnnotation("Temp", "ann4", anns); + ann4.setSequenceRef(seq1); + AlignmentAnnotation ann5 = new AlignmentAnnotation("Temp", "ann5", anns); + ann5.setSequenceRef(seq2); + AlignmentAnnotation ann6 = new AlignmentAnnotation("Temp", "ann6", anns); + AlignmentI al = new Alignment(new SequenceI[] {seq1, seq2, seq3}); + al.addAnnotation(ann1); // Structure for Seq1 + al.addAnnotation(ann2); // Structure for Seq2 + al.addAnnotation(ann3); // Structure for no sequence + al.addAnnotation(ann4); // Temp for seq1 + al.addAnnotation(ann5); // Temp for seq2 + al.addAnnotation(ann6); // Temp for no sequence + List types = new ArrayList(); + List scope = new ArrayList(); + + /* + * Set all sequence related Structure to hidden (ann1, ann2) + */ + types.add("Structure"); + AlignmentUtils.showOrHideSequenceAnnotations(al, types, null, false, + false); + assertFalse(ann1.visible); + assertFalse(ann2.visible); + assertTrue(ann3.visible); // not sequence-related, not affected + assertTrue(ann4.visible); // not Structure, not affected + assertTrue(ann5.visible); // " + assertTrue(ann6.visible); // not sequence-related, not affected + + /* + * Set Temp in {seq1, seq3} to hidden + */ + types.clear(); + types.add("Temp"); + scope.add(seq1); + scope.add(seq3); + AlignmentUtils.showOrHideSequenceAnnotations(al, types, scope, false, + false); + assertFalse(ann1.visible); // unchanged + assertFalse(ann2.visible); // unchanged + assertTrue(ann3.visible); // not sequence-related, not affected + assertFalse(ann4.visible); // Temp for seq1 hidden + assertTrue(ann5.visible); // not in scope, not affected + assertTrue(ann6.visible); // not sequence-related, not affected + + /* + * Set Temp in all sequences to hidden + */ + types.clear(); + types.add("Temp"); + scope.add(seq1); + scope.add(seq3); + AlignmentUtils.showOrHideSequenceAnnotations(al, types, null, false, + false); + assertFalse(ann1.visible); // unchanged + assertFalse(ann2.visible); // unchanged + assertTrue(ann3.visible); // not sequence-related, not affected + assertFalse(ann4.visible); // Temp for seq1 hidden + assertFalse(ann5.visible); // Temp for seq2 hidden + assertTrue(ann6.visible); // not sequence-related, not affected + + /* + * Set all types in {seq1, seq3} to visible + */ + types.clear(); + scope.clear(); + scope.add(seq1); + scope.add(seq3); + AlignmentUtils.showOrHideSequenceAnnotations(al, types, scope, true, + true); + assertTrue(ann1.visible); // Structure for seq1 set visible + assertFalse(ann2.visible); // not in scope, unchanged + assertTrue(ann3.visible); // not sequence-related, not affected + assertTrue(ann4.visible); // Temp for seq1 set visible + assertFalse(ann5.visible); // not in scope, unchanged + assertTrue(ann6.visible); // not sequence-related, not affected + + /* + * Set all types in all scope to hidden + */ + AlignmentUtils.showOrHideSequenceAnnotations(al, types, null, true, + false); + assertFalse(ann1.visible); + assertFalse(ann2.visible); + assertTrue(ann3.visible); // not sequence-related, not affected + assertFalse(ann4.visible); + assertFalse(ann5.visible); + assertTrue(ann6.visible); // not sequence-related, not affected } } diff --git a/test/jalview/analysis/CodingUtilsTest.java b/test/jalview/analysis/CodingUtilsTest.java new file mode 100644 index 0000000..0f235fb --- /dev/null +++ b/test/jalview/analysis/CodingUtilsTest.java @@ -0,0 +1,78 @@ +package jalview.analysis; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.junit.Test; + +public class CodingUtilsTest +{ + + @Test + public void testDecodeCodon() + { + assertTrue(Arrays.equals(new char[] + { 'A', 'A', 'A' }, CodingUtils.decodeCodon(0))); + assertTrue(Arrays.equals(new char[] + { 'A', 'A', 'C' }, CodingUtils.decodeCodon(1))); + assertTrue(Arrays.equals(new char[] + { 'A', 'A', 'G' }, CodingUtils.decodeCodon(2))); + assertTrue(Arrays.equals(new char[] + { 'A', 'A', 'T' }, CodingUtils.decodeCodon(3))); + assertTrue(Arrays.equals(new char[] + { 'A', 'C', 'A' }, CodingUtils.decodeCodon(4))); + assertTrue(Arrays.equals(new char[] + { 'C', 'A', 'A' }, CodingUtils.decodeCodon(16))); + assertTrue(Arrays.equals(new char[] + { 'G', 'G', 'G' }, CodingUtils.decodeCodon(42))); + assertTrue(Arrays.equals(new char[] + { 'T', 'T', 'T' }, CodingUtils.decodeCodon(63))); + } + + @Test + public void testDecodeNucleotide() + { + assertEquals('A', CodingUtils.decodeNucleotide(0)); + assertEquals('C', CodingUtils.decodeNucleotide(1)); + assertEquals('G', CodingUtils.decodeNucleotide(2)); + assertEquals('T', CodingUtils.decodeNucleotide(3)); + assertEquals('0', CodingUtils.decodeNucleotide(4)); + } + + @Test + public void testEncodeCodon() + { + assertTrue(CodingUtils.encodeCodon('Z') < 0); + assertEquals(0, CodingUtils.encodeCodon('a')); + assertEquals(0, CodingUtils.encodeCodon('A')); + assertEquals(1, CodingUtils.encodeCodon('c')); + assertEquals(1, CodingUtils.encodeCodon('C')); + assertEquals(2, CodingUtils.encodeCodon('g')); + assertEquals(2, CodingUtils.encodeCodon('G')); + assertEquals(3, CodingUtils.encodeCodon('t')); + assertEquals(3, CodingUtils.encodeCodon('T')); + assertEquals(3, CodingUtils.encodeCodon('u')); + assertEquals(3, CodingUtils.encodeCodon('U')); + + assertEquals(-1, CodingUtils.encodeCodon(null)); + assertEquals(0, CodingUtils.encodeCodon(new char[] + { 'A', 'A', 'A' })); + assertEquals(1, CodingUtils.encodeCodon(new char[] + { 'A', 'A', 'C' })); + assertEquals(2, CodingUtils.encodeCodon(new char[] + { 'A', 'A', 'G' })); + assertEquals(3, CodingUtils.encodeCodon(new char[] + { 'A', 'A', 'T' })); + assertEquals(4, CodingUtils.encodeCodon(new char[] + { 'A', 'C', 'A' })); + assertEquals(16, CodingUtils.encodeCodon(new char[] + { 'C', 'A', 'A' })); + assertEquals(42, CodingUtils.encodeCodon(new char[] + { 'G', 'G', 'G' })); + assertEquals(63, CodingUtils.encodeCodon(new char[] + { 'T', 'T', 'T' })); + } + +} diff --git a/test/jalview/analysis/CrossRefTest.java b/test/jalview/analysis/CrossRefTest.java new file mode 100644 index 0000000..2ae4afc --- /dev/null +++ b/test/jalview/analysis/CrossRefTest.java @@ -0,0 +1,72 @@ +package jalview.analysis; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import jalview.datamodel.DBRefEntry; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; + +import org.junit.Test; + +public class CrossRefTest +{ + + /** + * Tests for the method that checks if one sequence cross-references another + */ + @Test + public void testHasCrossRef() + { + assertFalse(CrossRef.hasCrossRef(null, null)); + SequenceI seq1 = new Sequence("EMBL|A12345", "ABCDEF"); + assertFalse(CrossRef.hasCrossRef(seq1, null)); + assertFalse(CrossRef.hasCrossRef(null, seq1)); + SequenceI seq2 = new Sequence("UNIPROT|V20192", "ABCDEF"); + assertFalse(CrossRef.hasCrossRef(seq1, seq2)); + + // different ref + seq1.addDBRef(new DBRefEntry("UNIPROT", "1", "v20193")); + assertFalse(CrossRef.hasCrossRef(seq1, seq2)); + + // case-insensitive; version number is ignored + seq1.addDBRef(new DBRefEntry("UNIPROT", "1", "v20192")); + assertTrue(CrossRef.hasCrossRef(seq1, seq2)); + + // right case! + seq1.addDBRef(new DBRefEntry("UNIPROT", "1", "V20192")); + assertTrue(CrossRef.hasCrossRef(seq1, seq2)); + // test is one-way only + assertFalse(CrossRef.hasCrossRef(seq2, seq1)); + } + + /** + * Tests for the method that checks if either sequence cross-references the + * other + */ + @Test + public void testHaveCrossRef() + { + assertFalse(CrossRef.hasCrossRef(null, null)); + SequenceI seq1 = new Sequence("EMBL|A12345", "ABCDEF"); + assertFalse(CrossRef.haveCrossRef(seq1, null)); + assertFalse(CrossRef.haveCrossRef(null, seq1)); + SequenceI seq2 = new Sequence("UNIPROT|V20192", "ABCDEF"); + assertFalse(CrossRef.haveCrossRef(seq1, seq2)); + + seq1.addDBRef(new DBRefEntry("UNIPROT", "1", "V20192")); + assertTrue(CrossRef.haveCrossRef(seq1, seq2)); + // next is true for haveCrossRef, false for hasCrossRef + assertTrue(CrossRef.haveCrossRef(seq2, seq1)); + + // now the other way round + seq1.setDBRef(null); + seq2.addDBRef(new DBRefEntry("EMBL", "1", "A12345")); + assertTrue(CrossRef.haveCrossRef(seq1, seq2)); + assertTrue(CrossRef.haveCrossRef(seq2, seq1)); + + // now both ways + seq1.addDBRef(new DBRefEntry("UNIPROT", "1", "V20192")); + assertTrue(CrossRef.haveCrossRef(seq1, seq2)); + assertTrue(CrossRef.haveCrossRef(seq2, seq1)); + } +} diff --git a/test/jalview/analysis/DnaAlignmentGenerator.java b/test/jalview/analysis/DnaAlignmentGenerator.java new file mode 100644 index 0000000..1b8964f --- /dev/null +++ b/test/jalview/analysis/DnaAlignmentGenerator.java @@ -0,0 +1,253 @@ +package jalview.analysis; + +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; +import jalview.io.FastaFile; + +import java.util.Arrays; +import java.util.Random; + +/** + * Generates, and outputs in Fasta format, a random DNA alignment for given + * sequence length and count. Will regenerate the same alignment each time if + * the same random seed is used (so may be used for reproducible unit tests). + * Not guaranteed to reproduce the same results between versions, as the rules + * may get tweaked to produce more 'realistic' results. + * + * Arguments: + *

    + *
  • length (number of bases in each sequence)
  • + *
  • height (number of sequences)
  • + *
  • a whole number random seed
  • + *
  • percentage of gaps to include (0-100)
  • + *
  • percentage chance of variation of each position (0-100)
  • + *
+ * + * @author gmcarstairs + * + */ +public class DnaAlignmentGenerator +{ + private static final char GAP = '-'; + + private static final char ZERO = '0'; + + private static final char[] BASES = new char[] + { 'G', 'T', 'C', 'A' }; + + private Random random; + + /** + * Outputs a DNA 'alignment' where each position is a random choice from + * 'GTCA-'. + * + * @param args + */ + public static void main(String[] args) + { + if (args.length != 5) + { + usage(); + return; + } + int width = Integer.parseInt(args[0]); + int height = Integer.parseInt(args[1]); + long randomSeed = Long.valueOf(args[2]); + int gapPercentage = Integer.valueOf(args[3]); + int changePercentage = Integer.valueOf(args[4]); + AlignmentI al = new DnaAlignmentGenerator().generate(width, height, + randomSeed, gapPercentage, changePercentage); + + System.out.println("; " + height + " sequences of " + width + + " bases with " + gapPercentage + "% gaps and " + + changePercentage + "% mutations (random seed = " + randomSeed + + ")"); + System.out.println(new FastaFile().print(al.getSequencesArray())); + } + + /** + * Print parameter help. + */ + private static void usage() + { + System.out.println("Usage:"); + System.out.println("arg0: number of (non-gap) bases per sequence"); + System.out.println("arg1: number sequences"); + System.out + .println("arg2: an integer as random seed (same seed = same results)"); + System.out.println("arg3: percentage of gaps to (randomly) generate"); + System.out + .println("arg4: percentage of 'mutations' to (randomly) generate"); + System.out.println("Example: DnaAlignmentGenerator 12 15 387 10 5"); + System.out + .println("- 15 sequences of 12 bases each, approx 10% gaps and 5% mutations, random seed = 387"); + + } + + /** + * Default constructor + */ + public DnaAlignmentGenerator() + { + + } + + /** + * Outputs a DNA 'alignment' of given width and height, where each position is + * a random choice from 'GTCA-'. + * + * @param width + * @param height + * @param randomSeed + * @param changePercentage + * @param gapPercentage + */ + public AlignmentI generate(int width, int height, long randomSeed, + int gapPercentage, int changePercentage) + { + SequenceI[] seqs = new SequenceI[height]; + random = new Random(randomSeed); + seqs[0] = generateSequence(1, width, gapPercentage); + for (int seqno = 1; seqno < height; seqno++) + { + seqs[seqno] = generateAnotherSequence(seqs[0].getSequence(), + seqno + 1, width, changePercentage); + } + AlignmentI al = new Alignment(seqs); + return al; + } + + /** + * Outputs a DNA 'sequence' of given length, with some random gaps included. + * + * @param seqno + * @param length + * @param gapPercentage + */ + private SequenceI generateSequence(int seqno, int length, + int gapPercentage) + { + StringBuilder seq = new StringBuilder(length); + + /* + * Loop till we've added 'length' bases (excluding gaps) + */ + for (int count = 0; count < length;) + { + boolean addGap = random.nextInt(100) < gapPercentage; + char c = addGap ? GAP : BASES[random.nextInt(Integer.MAX_VALUE) % 4]; + seq.append(c); + if (!addGap) + { + count++; + } + } + final String seqName = "SEQ" + seqno; + final String seqString = seq.toString(); + SequenceI sq = new Sequence(seqName, seqString); + sq.createDatasetSequence(); + return sq; + } + + /** + * Generate a sequence approximately aligned to the first one. + * + * @param ds + * @param seqno + * @param width + * number of bases + * @param changePercentage + * @return + */ + private SequenceI generateAnotherSequence(char[] ds, int seqno, + int width, int changePercentage) + { + int length = ds.length; + char[] seq = new char[length]; + Arrays.fill(seq, ZERO); + int gapsWanted = length - width; + int gapsAdded = 0; + + /* + * First 'randomly' mimic gaps in model sequence. + */ + for (int pos = 0; pos < length; pos++) + { + if (ds[pos] == GAP) + { + /* + * Add a gap at the same position with changePercentage likelihood + */ + seq[pos] = randomCharacter(GAP, changePercentage); + if (seq[pos] == GAP) + { + gapsAdded++; + } + } + } + + /* + * Next scatter any remaining gaps (if any) at random. This gives an even + * distribution. + */ + while (gapsAdded < gapsWanted) + { + boolean added = false; + while (!added) + { + int pos = random.nextInt(length); + if (seq[pos] != GAP) + { + seq[pos] = GAP; + added = true; + gapsAdded++; + } + } + } + + /* + * Finally fill in the rest with randomly mutated bases. + */ + for (int pos = 0; pos < length; pos++) + { + if (seq[pos] == ZERO) + { + char c = randomCharacter(ds[pos], changePercentage); + seq[pos] = c; + } + } + final String seqName = "SEQ" + seqno; + final String seqString = new String(seq); + SequenceI sq = new Sequence(seqName, seqString); + sq.createDatasetSequence(); + return sq; + } + + /** + * Returns a random character that is changePercentage% likely to match the + * given type (as base or gap). + * + * @param changePercentage + * + * @param c + * @return + */ + private char randomCharacter(char c, int changePercentage) + { + final boolean mutation = random.nextInt(100) < changePercentage; + + if (!mutation) + { + return c; + } + + char newchar = c; + while (newchar == c) + { + newchar = BASES[random.nextInt(Integer.MAX_VALUE) % 4]; + } + return newchar; + } +} diff --git a/test/jalview/analysis/DnaTest.java b/test/jalview/analysis/DnaTest.java new file mode 100644 index 0000000..01ed183 --- /dev/null +++ b/test/jalview/analysis/DnaTest.java @@ -0,0 +1,445 @@ +package jalview.analysis; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import jalview.api.AlignViewportI; +import jalview.datamodel.AlignedCodon; +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.ColumnSelection; +import jalview.datamodel.SequenceI; +import jalview.gui.AlignViewport; +import jalview.io.FormatAdapter; + +import java.io.IOException; + +import org.junit.Test; + +public class DnaTest +{ + // @formatter:off + // AA encoding codons as ordered on the Jalview help page Amino Acid Table + private static String fasta = ">B\n" + "GCT" + "GCC" + "GCA" + "GCG" + + "TGT" + "TGC" + "GAT" + "GAC" + "GAA" + "GAG" + "TTT" + "TTC" + + "GGT" + "GGC" + "GGA" + "GGG" + "CAT" + "CAC" + "ATT" + "ATC" + + "ATA" + "AAA" + "AAG" + "TTG" + "TTA" + "CTT" + "CTC" + "CTA" + + "CTG" + "ATG" + "AAT" + "AAC" + "CCT" + "CCC" + "CCA" + "CCG" + + "CAA" + "CAG" + "CGT" + "CGC" + "CGA" + "CGG" + "AGA" + "AGG" + + "TCT" + "TCC" + "TCA" + "TCG" + "AGT" + "AGC" + "ACT" + "ACC" + + "ACA" + "ACG" + "GTT" + "GTC" + "GTA" + "GTG" + "TGG" + "TAT" + + "TAC" + "TAA" + "TAG" + "TGA"; + + private static String JAL_1312_example_align_fasta = ">B.FR.83.HXB2_LAI_IIIB_BRU_K03455/45-306\n" + + "ATGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAATTAAAACATATAGTATGGGCAAGCAG\n" + + "GGAGCTAGAACGATTCGCAGTTAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATACTGGGACA\n" + + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAGATCATTATATAATACAGTAGCAACCCTCTATTG\n" + + "TGTGCATCAAAGGATAGAGATAAAAGACACCAAGGAAGCTTTAGAC\n" + + ">gi|27804621|gb|AY178912.1|/1-259\n" + + "-TGGGAGAA-ATTCGGTT-CGGCCAGGGGGAAAGAAAAAATATCAGTTAAAACATATAGTATGGGCAAGCAG\n" + + "AGAGCTAGAACGATTCGCAGTTAACCCTGGCCTTTTAGAGACATCACAAGGCTGTAGACAAATACTGGGACA\n" + + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" + + "TGTTCATCAAAGGATAGATATAAAAGACACCAAGGAAGCTTTAGAT\n" + + ">gi|27804623|gb|AY178913.1|/1-259\n" + + "-TGGGAGAA-ATTCGGTT-CGGCCAGGGGGAAAGAAAAAATATCAGTTAAAACATATAGTATGGGCAAGCAG\n" + + "AGAGCTAGAACGATTCGCAGTTAACCCTGGCCTTTTAGAGACATCACAAGGCTGTAGACAAATACTGGAACA\n" + + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" + + "TGTTCATCAAAGGATAGATGTAAAAGACACCAAGGAAGCTTTAGAT\n" + + ">gi|27804627|gb|AY178915.1|/1-260\n" + + "-TGGGAAAA-ATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" + + "GGAGCTAGAACGATTCGCAGTTAACCCTGGCCTGTTAGAAACATCAGAAGGTTGTAGACAAATATTGGGACA\n" + + "GCTACAACCATCCCTTGAGACAGGATCAGAAGAACTTAAATCATTATWTAATACCATAGCAGTCCTCTATTG\n" + + "TGTACATCAAAGGATAGATATAAAAGACACCAAGGAAGCTTTAGAG\n" + + ">gi|27804631|gb|AY178917.1|/1-261\n" + + "-TGGGAAAAAATTCGGTTGAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" + + "GGAGCTAGAACGATTCGCAGTCAACCCTGGCCTGTTAGAAACACCAGAAGGCTGTAGACAAATACTGGGACA\n" + + "GCTACAACCGTCCCTTCAGACAGGATCGGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" + + "TGTGCATCAAAGGATAGATGTAAAAGACACCAAGGAGGCTTTAGAC\n" + + ">gi|27804635|gb|AY178919.1|/1-261\n" + + "-TGGGAGAGAATTCGGTTACGGCCAGGAGGAAAGAAAAAATATAAATTGAAACATATAGTATGGGCAGGCAG\n" + + "AGAGCTAGATCGATTCGCAGTCAATCCTGGCCTGTTAGAAACATCAGAAGGCTGCAGACAGATATTGGGACA\n" + + "GCTACAACCGTCCCTTAAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" + + "TGTACATCAAAGGATAGATGTAAAAGACACCAAGGAAGCTTTAGAT\n" + + ">gi|27804641|gb|AY178922.1|/1-261\n" + + "-TGGGAGAAAATTCGGTTACGGCCAGGGGGAAAGAAAAGATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" + + "GGAGCTAGAACGATTCGCAGTCAACCCTGGCCTGTTAGAAACATCAGAAGGCTGCAGACAAATACTGGGACA\n" + + "GTTACACCCATCCCTTCATACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" + + "TGTGCATCAAAGGATAGAAGTAAAAGACACCAAGGAAGCTTTAGAC\n" + + ">gi|27804647|gb|AY178925.1|/1-261\n" + + "-TGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATCAATTAAAACATGTAGTATGGGCAAGCAG\n" + + "GGAACTAGAACGATTCGCAGTTAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATATTGGGACA\n" + + "GCTACAACCATCCCTTCAGACAGGATCAGAGGAACTTAAATCATTATTTAATACAGTAGCAGTCCTCTATTG\n" + + "TGTACATCAAAGAATAGATGTAAAAGACACCAAGGAAGCTCTAGAA\n" + + ">gi|27804649|gb|AY178926.1|/1-261\n" + + "-TGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" + + "GGAGCTAGAACGATTCGCGGTCAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAACTACTGGGACA\n" + + "GTTACAACCATCCCTTCAGACAGGATCAGAAGAACTCAAATCATTATATAATACAATAGCAACCCTCTATTG\n" + + "TGTGCATCAAAGGATAGAGATAAAAGACACCAAGGAAGCCTTAGAT\n" + + ">gi|27804653|gb|AY178928.1|/1-261\n" + + "-TGGGAAAGAATTCGGTTAAGGCCAGGGGGAAAGAAACAATATAAATTAAAACATATAGTATGGGCAAGCAG\n" + + "GGAGCTAGACCGATTCGCACTTAACCCCGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATATTGGGACA\n" + + "GCTACAATCGTCCCTTCAGACAGGATCAGAAGAACTTAGATCACTATATAATACAGTAGCAGTCCTCTATTG\n" + + "TGTGCATCAAAAGATAGATGTAAAAGACACCAAGGAAGCCTTAGAC\n" + + ">gi|27804659|gb|AY178931.1|/1-261\n" + + "-TGGGAAAAAATTCGGTTACGGCCAGGAGGAAAGAAAAGATATAAATTAAAACATATAGTATGGGCAAGCAG\n" + + "GGAGCTAGAACGATTYGCAGTTAATCCTGGCCTTTTAGAAACAGCAGAAGGCTGTAGACAAATACTGGGACA\n" + + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" + + "TGTACATCAAAGGATAGAGATAAAAGACACCAAGGAAGCTTTAGAA\n"; + // @formatter:on + + /** + * Corner case for this test is the presence of codons after codons that were + * not translated. + * + * @throws IOException + */ + @Test + public void testTranslateCdna_withUntranslatableCodons() + throws IOException + { + AlignmentI alf = new FormatAdapter().readFile( + JAL_1312_example_align_fasta, jalview.io.FormatAdapter.PASTE, + "FASTA"); + ColumnSelection cs = new ColumnSelection(); + AlignViewportI av = new AlignViewport(alf, cs); + Dna dna = new Dna(av, new int[] + { 0, alf.getWidth() - 1 }); + AlignmentI translated = dna.translateCdna(); + assertNotNull("Couldn't do a full width translation of test data.", + translated); + } + + /** + * Test variant in which 15 column blocks at a time are translated (the rest + * hidden). + * + * @throws IOException + */ + @Test + public void testTranslateCdna_withUntranslatableCodonsAndHiddenColumns() + throws IOException + { + AlignmentI alf = new FormatAdapter().readFile( + JAL_1312_example_align_fasta, jalview.io.FormatAdapter.PASTE, + "FASTA"); + int vwidth = 15; + for (int ipos = 0; ipos + vwidth < alf.getWidth(); ipos += vwidth) + { + ColumnSelection cs = new ColumnSelection(); + if (ipos > 0) + { + cs.hideColumns(0, ipos - 1); + } + cs.hideColumns(ipos + vwidth, alf.getWidth()); + int[] vcontigs = cs.getVisibleContigs(0, alf.getWidth()); + AlignViewportI av = new AlignViewport(alf, cs); + Dna dna = new Dna(av, vcontigs); + AlignmentI transAlf = dna.translateCdna(); + + assertTrue("Translation failed (ipos=" + ipos + + ") No alignment data.", transAlf != null); + assertTrue("Translation failed (ipos=" + ipos + ") Empty alignment.", + transAlf.getHeight() > 0); + assertTrue("Translation failed (ipos=" + ipos + ") Translated " + + transAlf.getHeight() + " sequences from " + alf.getHeight() + + " sequences", alf.getHeight() == transAlf.getHeight()); + } + } + + /** + * Test simple translation to Amino Acids (with STOP codons translated to X). + * + * @throws IOException + */ + @Test + public void testTranslateCdna_simple() throws IOException + { + AlignmentI alf = new FormatAdapter().readFile(fasta, + FormatAdapter.PASTE, "FASTA"); + ColumnSelection cs = new ColumnSelection(); + AlignViewportI av = new AlignViewport(alf, cs); + Dna dna = new Dna(av, new int[] + { 0, alf.getWidth() - 1 }); + AlignmentI translated = dna.translateCdna(); + String aa = translated.getSequenceAt(0).getSequenceAsString(); + assertEquals( + "AAAACCDDEEFFGGGGHHIIIKKLLLLLLMNNPPPPQQRRRRRRSSSSSSTTTTVVVVWYYXXX", + aa); + } + + /** + * Test translation excluding hidden columns. + * + * @throws IOException + */ + @Test + public void testTranslateCdna_hiddenColumns() throws IOException + { + AlignmentI alf = new FormatAdapter().readFile(fasta, + FormatAdapter.PASTE, "FASTA"); + ColumnSelection cs = new jalview.datamodel.ColumnSelection(); + cs.hideColumns(6, 14); // hide codons 3/4/5 + cs.hideColumns(24, 35); // hide codons 9-12 + cs.hideColumns(177, 191); // hide codons 60-64 + AlignViewportI av = new AlignViewport(alf, cs); + Dna dna = new Dna(av, new int[] + { 0, alf.getWidth() - 1 }); + AlignmentI translated = dna.translateCdna(); + String aa = translated.getSequenceAt(0).getSequenceAsString(); + assertEquals("AACDDGGGGHHIIIKKLLLLLLMNNPPPPQQRRRRRRSSSSSSTTTTVVVVW", aa); + } + + /** + * Use this test to help debug into any cases of interest. + */ + @Test + public void testCompareCodonPos_oneOnly() + { + assertFollows("-AA--A", "G--GG"); // 2 shifted seq2, 3 shifted seq1 + } + + /** + * Tests for method that compares 'alignment' of two codon position triplets. + */ + @Test + public void testCompareCodonPos() + { + /* + * Returns 0 for any null argument + */ + assertEquals(0, Dna.compareCodonPos(new AlignedCodon(1, 2, 3), null)); + assertEquals(0, Dna.compareCodonPos(null, new AlignedCodon(1, 2, 3))); + + /* + * Work through 27 combinations. First 9 cases where first position matches. + */ + assertMatches("AAA", "GGG"); // 2 and 3 match + assertFollows("AA-A", "GGG"); // 2 matches, 3 shifted seq1 + assertPrecedes("AAA", "GG-G"); // 2 matches, 3 shifted seq2 + assertFollows("A-AA", "GG-G"); // 2 shifted seq1, 3 matches + assertFollows("A-A-A", "GG-G"); // 2 shifted seq1, 3 shifted seq1 + assertPrecedes("A-AA", "GG--G"); // 2 shifted seq1, 3 shifted seq2 + assertPrecedes("AA-A", "G-GG"); // 2 shifted seq2, 3 matches + assertFollows("AA--A", "G-GG"); // 2 shifted seq2, 3 shifted seq1 + assertPrecedes("AAA", "G-GG"); // 2 shifted seq2, 3 shifted seq2 + + /* + * 9 cases where first position is shifted in first sequence. + */ + assertFollows("-AAA", "G-GG"); // 2 and 3 match + assertFollows("-AA-A", "G-GG"); // 2 matches, 3 shifted seq1 + // 'enclosing' case: pick first to start precedes + assertFollows("-AAA", "G-G-G"); // 2 matches, 3 shifted seq2 + assertFollows("-A-AA", "G-G-G"); // 2 shifted seq1, 3 matches + assertFollows("-A-A-A", "G-G-G"); // 2 shifted seq1, 3 shifted seq1 + // 'enclosing' case: pick first to start precedes + assertFollows("-A-AA", "G-G--G"); // 2 shifted seq1, 3 shifted seq2 + assertFollows("-AA-A", "G--GG"); // 2 shifted seq2, 3 matches + assertFollows("-AA--A", "G--GG"); // 2 shifted seq2, 3 shifted seq1 + assertPrecedes("-AAA", "G--GG"); // 2 shifted seq2, 3 shifted seq2 + + /* + * 9 cases where first position is shifted in second sequence. + */ + assertPrecedes("A-AA", "-GGG"); // 2 and 3 match + assertPrecedes("A-A-A", "-GGG"); // 2 matches, 3 shifted seq1 + assertPrecedes("A-AA", "-GG-G"); // 2 matches, 3 shifted seq2 + assertPrecedes("A--AA", "-GG-G"); // 2 shifted seq1, 3 matches + // 'enclosing' case with middle base deciding: + assertFollows("A--AA", "-GGG"); // 2 shifted seq1, 3 shifted seq1 + assertPrecedes("A--AA", "-GG--G"); // 2 shifted seq1, 3 shifted seq2 + assertPrecedes("AA-A", "-GGG"); // 2 shifted seq2, 3 matches + assertPrecedes("AA--A", "-GGG"); // 2 shifted seq2, 3 shifted seq1 + assertPrecedes("AAA", "-GGG"); // 2 shifted seq2, 3 shifted seq2 + } + + /** + * This test generates a random cDNA alignment and its translation, then + * reorders the cDNA and retranslates, and verifies that the translations are + * the same (apart from ordering). + */ + @Test + public void testTranslateCdna_sequenceOrderIndependent() + { + /* + * Generate cDNA - 8 sequences of 12 bases each. + */ + AlignmentI cdna = new DnaAlignmentGenerator().generate(12, 8, 97, 5, 5); + ColumnSelection cs = new ColumnSelection(); + AlignViewportI av = new AlignViewport(cdna, cs); + Dna dna = new Dna(av, new int[] + { 0, cdna.getWidth() - 1 }); + AlignmentI translated = dna.translateCdna(); + + /* + * Jumble the cDNA sequences and translate. + */ + SequenceI[] sorted = new SequenceI[cdna.getHeight()]; + final int[] jumbler = new int[] + { 6, 7, 3, 4, 2, 0, 1, 5 }; + int seqNo = 0; + for (int i : jumbler) + { + sorted[seqNo++] = cdna.getSequenceAt(i); + } + AlignmentI cdnaReordered = new Alignment(sorted); + av = new AlignViewport(cdnaReordered, cs); + dna = new Dna(av, new int[] + { 0, cdna.getWidth() - 1 }); + AlignmentI translated2 = dna.translateCdna(); + + /* + * Check translated sequences are the same in both alignments. + */ + System.out.println("Original"); + System.out.println(translated.toString()); + System.out.println("Sorted"); + System.out.println(translated2.toString()); + + int sortedSequenceIndex = 0; + for (int originalSequenceIndex : jumbler) + { + final String translation1 = translated.getSequenceAt( + originalSequenceIndex).getSequenceAsString(); + final String translation2 = translated2.getSequenceAt(sortedSequenceIndex) + .getSequenceAsString(); + assertEquals(translation2, translation1); + sortedSequenceIndex++; + } + } + + /** + * Test that all the cases in testCompareCodonPos have a 'symmetric' + * comparison (without checking the actual comparison result). + */ + @Test + public void testCompareCodonPos_isSymmetric() + { + assertSymmetric("AAA", "GGG"); + assertSymmetric("AA-A", "GGG"); + assertSymmetric("AAA", "GG-G"); + assertSymmetric("A-AA", "GG-G"); + assertSymmetric("A-A-A", "GG-G"); + assertSymmetric("A-AA", "GG--G"); + assertSymmetric("AA-A", "G-GG"); + assertSymmetric("AA--A", "G-GG"); + assertSymmetric("AAA", "G-GG"); + assertSymmetric("-AAA", "G-GG"); + assertSymmetric("-AA-A", "G-GG"); + assertSymmetric("-AAA", "G-G-G"); + assertSymmetric("-A-AA", "G-G-G"); + assertSymmetric("-A-A-A", "G-G-G"); + assertSymmetric("-A-AA", "G-G--G"); + assertSymmetric("-AA-A", "G--GG"); + assertSymmetric("-AA--A", "G--GG"); + assertSymmetric("-AAA", "G--GG"); + assertSymmetric("A-AA", "-GGG"); + assertSymmetric("A-A-A", "-GGG"); + assertSymmetric("A-AA", "-GG-G"); + assertSymmetric("A--AA", "-GG-G"); + assertSymmetric("A--AA", "-GGG"); + assertSymmetric("A--AA", "-GG--G"); + assertSymmetric("AA-A", "-GGG"); + assertSymmetric("AA--A", "-GGG"); + assertSymmetric("AAA", "-GGG"); + } + + private void assertSymmetric(String codon1, String codon2) + { + assertEquals("Comparison of '" + codon1 + "' and '" + codon2 + + " not symmetric", Integer.signum(compare(codon1, codon2)), + -Integer.signum(compare(codon2, codon1))); + } + + /** + * Assert that the first sequence should map to the same position as the + * second in a translated alignment. Also checks that this is true if the + * order of the codons is reversed. + * + * @param codon1 + * @param codon2 + */ + private void assertMatches(String codon1, String codon2) + { + assertEquals("Expected '" + codon1 + "' matches '" + codon2 + "'", 0, + compare(codon1, codon2)); + assertEquals("Expected '" + codon2 + "' matches '" + codon1 + "'", 0, + compare(codon2, codon1)); + } + + /** + * Assert that the first sequence should precede the second in a translated + * alignment + * + * @param codon1 + * @param codon2 + */ + private void assertPrecedes(String codon1, String codon2) + { + assertEquals("Expected '" + codon1 + "' precedes '" + codon2 + "'", + -1, compare(codon1, codon2)); + } + + /** + * Assert that the first sequence should follow the second in a translated + * alignment + * + * @param codon1 + * @param codon2 + */ + private void assertFollows(String codon1, String codon2) + { + assertEquals("Expected '" + codon1 + "' follows '" + codon2 + "'", 1, + compare(codon1, codon2)); + } + + /** + * Convert two nucleotide strings to base positions and pass to + * Dna.compareCodonPos, return the result. + * + * @param s1 + * @param s2 + * @return + */ + private int compare(String s1, String s2) + { + final AlignedCodon cd1 = convertCodon(s1); + final AlignedCodon cd2 = convertCodon(s2); + System.out.println("K: " + s1 + " " + cd1.toString()); + System.out.println("G: " + s2 + " " + cd2.toString()); + System.out.println(); + return Dna.compareCodonPos(cd1, cd2); + } + + /** + * Convert a string e.g. "-GC-T" to base positions e.g. [1, 2, 4]. The string + * should have exactly 3 non-gap characters, and use '-' for gaps. + * + * @param s + * @return + */ + private AlignedCodon convertCodon(String s) + { + int[] codon = new int[3]; + int i = 0; + for (int j = 0; j < s.length(); j++) + { + if (s.charAt(j) != '-') + { + codon[i++] = j; + } + } + return new AlignedCodon(codon[0], codon[1], codon[2]); + } + + /** + * Weirdly, maybe worth a test to prove the helper method of this test class. + */ + @Test + public void testConvertCodon() + { + assertEquals("[0, 1, 2]", convertCodon("AAA").toString()); + assertEquals("[0, 2, 5]", convertCodon("A-A--A").toString()); + assertEquals("[1, 3, 4]", convertCodon("-A-AA-").toString()); + } +} diff --git a/test/jalview/analysis/DnaTranslation.java b/test/jalview/analysis/DnaTranslation.java deleted file mode 100644 index 9cedbb0..0000000 --- a/test/jalview/analysis/DnaTranslation.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * 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 . - * The Jalview Authors are detailed in the 'AUTHORS' file. - */ -package jalview.analysis; - -import static org.junit.Assert.*; -import jalview.datamodel.ColumnSelection; - -import java.io.IOException; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -public class DnaTranslation -{ - - private static String JAL_1312_example_align_fasta = ">B.FR.83.HXB2_LAI_IIIB_BRU_K03455/45-306\n" - + "ATGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAATTAAAACATATAGTATGGGCAAGCAG\n" - + "GGAGCTAGAACGATTCGCAGTTAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATACTGGGACA\n" - + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAGATCATTATATAATACAGTAGCAACCCTCTATTG\n" - + "TGTGCATCAAAGGATAGAGATAAAAGACACCAAGGAAGCTTTAGAC\n" - + ">gi|27804621|gb|AY178912.1|/1-259\n" - + "-TGGGAGAA-ATTCGGTT-CGGCCAGGGGGAAAGAAAAAATATCAGTTAAAACATATAGTATGGGCAAGCAG\n" - + "AGAGCTAGAACGATTCGCAGTTAACCCTGGCCTTTTAGAGACATCACAAGGCTGTAGACAAATACTGGGACA\n" - + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" - + "TGTTCATCAAAGGATAGATATAAAAGACACCAAGGAAGCTTTAGAT\n" - + ">gi|27804623|gb|AY178913.1|/1-259\n" - + "-TGGGAGAA-ATTCGGTT-CGGCCAGGGGGAAAGAAAAAATATCAGTTAAAACATATAGTATGGGCAAGCAG\n" - + "AGAGCTAGAACGATTCGCAGTTAACCCTGGCCTTTTAGAGACATCACAAGGCTGTAGACAAATACTGGAACA\n" - + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" - + "TGTTCATCAAAGGATAGATGTAAAAGACACCAAGGAAGCTTTAGAT\n" - + ">gi|27804627|gb|AY178915.1|/1-260\n" - + "-TGGGAAAA-ATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" - + "GGAGCTAGAACGATTCGCAGTTAACCCTGGCCTGTTAGAAACATCAGAAGGTTGTAGACAAATATTGGGACA\n" - + "GCTACAACCATCCCTTGAGACAGGATCAGAAGAACTTAAATCATTATWTAATACCATAGCAGTCCTCTATTG\n" - + "TGTACATCAAAGGATAGATATAAAAGACACCAAGGAAGCTTTAGAG\n" - + ">gi|27804631|gb|AY178917.1|/1-261\n" - + "-TGGGAAAAAATTCGGTTGAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" - + "GGAGCTAGAACGATTCGCAGTCAACCCTGGCCTGTTAGAAACACCAGAAGGCTGTAGACAAATACTGGGACA\n" - + "GCTACAACCGTCCCTTCAGACAGGATCGGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" - + "TGTGCATCAAAGGATAGATGTAAAAGACACCAAGGAGGCTTTAGAC\n" - + ">gi|27804635|gb|AY178919.1|/1-261\n" - + "-TGGGAGAGAATTCGGTTACGGCCAGGAGGAAAGAAAAAATATAAATTGAAACATATAGTATGGGCAGGCAG\n" - + "AGAGCTAGATCGATTCGCAGTCAATCCTGGCCTGTTAGAAACATCAGAAGGCTGCAGACAGATATTGGGACA\n" - + "GCTACAACCGTCCCTTAAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" - + "TGTACATCAAAGGATAGATGTAAAAGACACCAAGGAAGCTTTAGAT\n" - + ">gi|27804641|gb|AY178922.1|/1-261\n" - + "-TGGGAGAAAATTCGGTTACGGCCAGGGGGAAAGAAAAGATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" - + "GGAGCTAGAACGATTCGCAGTCAACCCTGGCCTGTTAGAAACATCAGAAGGCTGCAGACAAATACTGGGACA\n" - + "GTTACACCCATCCCTTCATACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" - + "TGTGCATCAAAGGATAGAAGTAAAAGACACCAAGGAAGCTTTAGAC\n" - + ">gi|27804647|gb|AY178925.1|/1-261\n" - + "-TGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATCAATTAAAACATGTAGTATGGGCAAGCAG\n" - + "GGAACTAGAACGATTCGCAGTTAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATATTGGGACA\n" - + "GCTACAACCATCCCTTCAGACAGGATCAGAGGAACTTAAATCATTATTTAATACAGTAGCAGTCCTCTATTG\n" - + "TGTACATCAAAGAATAGATGTAAAAGACACCAAGGAAGCTCTAGAA\n" - + ">gi|27804649|gb|AY178926.1|/1-261\n" - + "-TGGGAAAAAATTCGGTTAAGGCCAGGGGGAAAGAAAAAATATAAGTTAAAACATATAGTATGGGCAAGCAG\n" - + "GGAGCTAGAACGATTCGCGGTCAATCCTGGCCTGTTAGAAACATCAGAAGGCTGTAGACAACTACTGGGACA\n" - + "GTTACAACCATCCCTTCAGACAGGATCAGAAGAACTCAAATCATTATATAATACAATAGCAACCCTCTATTG\n" - + "TGTGCATCAAAGGATAGAGATAAAAGACACCAAGGAAGCCTTAGAT\n" - + ">gi|27804653|gb|AY178928.1|/1-261\n" - + "-TGGGAAAGAATTCGGTTAAGGCCAGGGGGAAAGAAACAATATAAATTAAAACATATAGTATGGGCAAGCAG\n" - + "GGAGCTAGACCGATTCGCACTTAACCCCGGCCTGTTAGAAACATCAGAAGGCTGTAGACAAATATTGGGACA\n" - + "GCTACAATCGTCCCTTCAGACAGGATCAGAAGAACTTAGATCACTATATAATACAGTAGCAGTCCTCTATTG\n" - + "TGTGCATCAAAAGATAGATGTAAAAGACACCAAGGAAGCCTTAGAC\n" - + ">gi|27804659|gb|AY178931.1|/1-261\n" - + "-TGGGAAAAAATTCGGTTACGGCCAGGAGGAAAGAAAAGATATAAATTAAAACATATAGTATGGGCAAGCAG\n" - + "GGAGCTAGAACGATTYGCAGTTAATCCTGGCCTTTTAGAAACAGCAGAAGGCTGTAGACAAATACTGGGACA\n" - + "GCTACAACCATCCCTTCAGACAGGATCAGAAGAACTTAAATCATTATATAATACAGTAGCAACCCTCTATTG\n" - + "TGTACATCAAAGGATAGAGATAAAAGACACCAAGGAAGCTTTAGAA\n"; - - @Test - public void translationWithUntranslatableCodonsTest() - { - // Corner case for this test is the presence of codons after codons that - // were not translated. - jalview.datamodel.AlignmentI alf = null; - try - { - alf = new jalview.io.FormatAdapter().readFile( - JAL_1312_example_align_fasta, jalview.io.FormatAdapter.PASTE, - "FASTA"); - } catch (IOException x) - { - x.printStackTrace(); - fail("Unexpected IOException (" + x.getMessage() - + ") - check test environment"); - } - { - // full translation - ColumnSelection cs = new jalview.datamodel.ColumnSelection(); - assertNotNull("Couldn't do a full width translation of test data.", - jalview.analysis.Dna.CdnaTranslate( - alf.getSequencesArray(), - cs.getVisibleSequenceStrings(0, alf.getWidth(), - alf.getSequencesArray()), new int[] - { 0, alf.getWidth() - 1 }, alf.getGapCharacter(), - null, alf.getWidth(), null)); - } - int vwidth = 15; // translate in 15 base stretches - for (int ipos = 0; ipos + vwidth < alf.getWidth(); ipos += vwidth) - { - ColumnSelection cs = new jalview.datamodel.ColumnSelection(); - if (ipos > 0) - { - cs.hideColumns(0, ipos - 1); - } - cs.hideColumns(ipos + vwidth, alf.getWidth()); - int[] vcontigs = cs.getVisibleContigs(0, alf.getWidth()); - String[] sel = cs.getVisibleSequenceStrings(0, alf.getWidth(), - alf.getSequencesArray()); - jalview.datamodel.AlignmentI transAlf = jalview.analysis.Dna - .CdnaTranslate(alf.getSequencesArray(), sel, vcontigs, - alf.getGapCharacter(), null, alf.getWidth(), null); - - assertTrue("Translation failed (ipos=" + ipos - + ") No alignment data.", transAlf != null); - assertTrue("Translation failed (ipos=" + ipos + ") Empty algnment.", - transAlf.getHeight() > 0); - assertTrue("Translation failed (ipos=" + ipos + ") Translated " - + transAlf.getHeight() + " sequences from " + alf.getHeight() - + " sequences", alf.getHeight() == transAlf.getHeight()); - } - - } -} diff --git a/test/jalview/analysis/TestAlignSeq.java b/test/jalview/analysis/TestAlignSeq.java index 65213e2..7352b94 100644 --- a/test/jalview/analysis/TestAlignSeq.java +++ b/test/jalview/analysis/TestAlignSeq.java @@ -20,7 +20,9 @@ */ package jalview.analysis; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import jalview.datamodel.Mapping; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; @@ -74,4 +76,13 @@ public class TestAlignSeq } } + @Test + public void testExtractGaps() + { + assertNull(AlignSeq.extractGaps(null, null)); + assertNull(AlignSeq.extractGaps(". -", null)); + assertNull(AlignSeq.extractGaps(null, "AB-C")); + + assertEquals("ABCD", AlignSeq.extractGaps(" .-", ". -A-B.C D.")); + } } diff --git a/test/jalview/commands/EditCommandTest.java b/test/jalview/commands/EditCommandTest.java index fc821b9..6ea05e6 100644 --- a/test/jalview/commands/EditCommandTest.java +++ b/test/jalview/commands/EditCommandTest.java @@ -1,6 +1,7 @@ package jalview.commands; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; import jalview.commands.EditCommand.Action; import jalview.commands.EditCommand.Edit; import jalview.datamodel.Alignment; @@ -8,6 +9,8 @@ import jalview.datamodel.AlignmentI; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; +import java.util.Map; + import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -33,9 +36,13 @@ public class EditCommandTest testee = new EditCommand(); seqs = new SequenceI[4]; seqs[0] = new Sequence("seq0", "abcdefghjk"); + seqs[0].setDatasetSequence(new Sequence("seq0ds", "abcdefghjk")); seqs[1] = new Sequence("seq1", "fghjklmnopq"); + seqs[1].setDatasetSequence(new Sequence("seq1ds", "fghjklmnopq")); seqs[2] = new Sequence("seq2", "qrstuvwxyz"); + seqs[2].setDatasetSequence(new Sequence("seq2ds", "qrstuvwxyz")); seqs[3] = new Sequence("seq3", "1234567890"); + seqs[3].setDatasetSequence(new Sequence("seq3ds", "1234567890")); al = new Alignment(seqs); al.setGapCharacter('?'); } @@ -227,6 +234,373 @@ public class EditCommandTest assertEquals("qrstuvwxyz", seqs[2].getSequenceAsString()); assertEquals("1234567890", seqs[3].getSequenceAsString()); seqs[1] = new Sequence("seq1", "fghjZXYnopq"); + } + + /** + * Test that the addEdit command correctly merges insert gap commands when + * possible. + */ + @Test + public void testAddEdit_multipleInsertGap() + { + /* + * 3 insert gap in a row (aka mouse drag right): + */ + Edit e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] + { seqs[0] }, 1, 1, al); + testee.addEdit(e); + SequenceI edited = new Sequence("seq0", "a?bcdefghjk"); + edited.setDatasetSequence(seqs[0].getDatasetSequence()); + e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] + { edited }, 2, 1, al); + testee.addEdit(e); + edited = new Sequence("seq0", "a??bcdefghjk"); + edited.setDatasetSequence(seqs[0].getDatasetSequence()); + e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] + { edited }, 3, 1, al); + testee.addEdit(e); + assertEquals(1, testee.getSize()); + assertEquals(Action.INSERT_GAP, testee.getEdit(0).getAction()); + assertEquals(1, testee.getEdit(0).getPosition()); + assertEquals(3, testee.getEdit(0).getNumber()); + + /* + * Add a non-contiguous edit - should not be merged. + */ + e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] + { edited }, 5, 2, al); + testee.addEdit(e); + assertEquals(2, testee.getSize()); + assertEquals(5, testee.getEdit(1).getPosition()); + assertEquals(2, testee.getEdit(1).getNumber()); + + /* + * Add a Delete after the Insert - should not be merged. + */ + e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[] + { edited }, 6, 2, al); + testee.addEdit(e); + assertEquals(3, testee.getSize()); + assertEquals(Action.DELETE_GAP, testee.getEdit(2).getAction()); + assertEquals(6, testee.getEdit(2).getPosition()); + assertEquals(2, testee.getEdit(2).getNumber()); + } + + /** + * Test that the addEdit command correctly merges delete gap commands when + * possible. + */ + @Test + public void testAddEdit_multipleDeleteGap() + { + /* + * 3 delete gap in a row (aka mouse drag left): + */ + seqs[0].setSequence("a???bcdefghjk"); + Edit e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[] + { seqs[0] }, 4, 1, al); + testee.addEdit(e); + assertEquals(1, testee.getSize()); + + SequenceI edited = new Sequence("seq0", "a??bcdefghjk"); + edited.setDatasetSequence(seqs[0].getDatasetSequence()); + e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[] + { edited }, 3, 1, al); + testee.addEdit(e); + assertEquals(1, testee.getSize()); + + edited = new Sequence("seq0", "a?bcdefghjk"); + edited.setDatasetSequence(seqs[0].getDatasetSequence()); + e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[] + { edited }, 2, 1, al); + testee.addEdit(e); + assertEquals(1, testee.getSize()); + assertEquals(Action.DELETE_GAP, testee.getEdit(0).getAction()); + assertEquals(2, testee.getEdit(0).getPosition()); + assertEquals(3, testee.getEdit(0).getNumber()); + + /* + * Add a non-contiguous edit - should not be merged. + */ + e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[] + { edited }, 2, 1, al); + testee.addEdit(e); + assertEquals(2, testee.getSize()); + assertEquals(Action.DELETE_GAP, testee.getEdit(0).getAction()); + assertEquals(2, testee.getEdit(1).getPosition()); + assertEquals(1, testee.getEdit(1).getNumber()); + + /* + * Add an Insert after the Delete - should not be merged. + */ + e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] + { edited }, 1, 1, al); + testee.addEdit(e); + assertEquals(3, testee.getSize()); + assertEquals(Action.INSERT_GAP, testee.getEdit(2).getAction()); + assertEquals(1, testee.getEdit(2).getPosition()); + assertEquals(1, testee.getEdit(2).getNumber()); + } + + /** + * Test that the addEdit command correctly handles 'remove gaps' edits for the + * case when they appear contiguous but are acting on different sequences. + * They should not be merged. + */ + @Test + public void testAddEdit_removeAllGaps() + { + seqs[0].setSequence("a???bcdefghjk"); + Edit e = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[] + { seqs[0] }, 4, 1, al); + testee.addEdit(e); + + seqs[1].setSequence("f??ghjklmnopq"); + Edit e2 = new EditCommand().new Edit(Action.DELETE_GAP, new SequenceI[] + { seqs[1] }, 3, 1, al); + testee.addEdit(e2); + assertEquals(2, testee.getSize()); + assertSame(e, testee.getEdit(0)); + assertSame(e2, testee.getEdit(1)); + } + + /** + * Test that the addEdit command correctly merges insert gap commands acting + * on a multi-sequence selection. + */ + @Test + public void testAddEdit_groupInsertGaps() + { + /* + * 2 insert gap in a row (aka mouse drag right), on two sequences: + */ + Edit e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] + { seqs[0], seqs[1] }, 1, 1, al); + testee.addEdit(e); + SequenceI seq1edited = new Sequence("seq0", "a?bcdefghjk"); + seq1edited.setDatasetSequence(seqs[0].getDatasetSequence()); + SequenceI seq2edited = new Sequence("seq1", "f?ghjklmnopq"); + seq2edited.setDatasetSequence(seqs[1].getDatasetSequence()); + e = new EditCommand().new Edit(Action.INSERT_GAP, new SequenceI[] + { seq1edited, seq2edited }, 2, 1, al); + testee.addEdit(e); + + assertEquals(1, testee.getSize()); + assertEquals(Action.INSERT_GAP, testee.getEdit(0).getAction()); + assertEquals(1, testee.getEdit(0).getPosition()); + assertEquals(2, testee.getEdit(0).getNumber()); + assertEquals(seqs[0].getDatasetSequence(), testee.getEdit(0) + .getSequences()[0].getDatasetSequence()); + assertEquals(seqs[1].getDatasetSequence(), testee.getEdit(0) + .getSequences()[1].getDatasetSequence()); + } + + /** + * Test for 'undoing' a series of gap insertions. + *
    + *
  • Start: ABCDEF insert 2 at pos 1
  • + *
  • next: A--BCDEF insert 1 at pos 4
  • + *
  • next: A--B-CDEF insert 2 at pos 0
  • + *
  • last: --A--B-CDEF
  • + *
+ */ + @Test + public void testPriorState_multipleInserts() + { + EditCommand command = new EditCommand(); + SequenceI seq = new Sequence("", "--A--B-CDEF"); + SequenceI ds = new Sequence("", "ABCDEF"); + seq.setDatasetSequence(ds); + SequenceI[] seqs = new SequenceI[] + { seq }; + Edit e = command.new Edit(Action.INSERT_GAP, seqs, 1, 2, '-'); + command.addEdit(e); + e = command.new Edit(Action.INSERT_GAP, seqs, 4, 1, '-'); + command.addEdit(e); + e = command.new Edit(Action.INSERT_GAP, seqs, 0, 2, '-'); + command.addEdit(e); + + Map unwound = command.priorState(false); + assertEquals("ABCDEF", unwound.get(ds).getSequenceAsString()); + } + + /** + * Test for 'undoing' a series of gap deletions. + *
    + *
  • Start: A-B-C delete 1 at pos 1
  • + *
  • Next: AB-C delete 1 at pos 2
  • + *
  • End: ABC
  • + *
+ */ + @Test + public void testPriorState_removeAllGaps() + { + EditCommand command = new EditCommand(); + SequenceI seq = new Sequence("", "ABC"); + SequenceI ds = new Sequence("", "ABC"); + seq.setDatasetSequence(ds); + SequenceI[] seqs = new SequenceI[] + { seq }; + Edit e = command.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'); + command.addEdit(e); + e = command.new Edit(Action.DELETE_GAP, seqs, 2, 1, '-'); + command.addEdit(e); + + Map unwound = command.priorState(false); + assertEquals("A-B-C", unwound.get(ds).getSequenceAsString()); + } + + /** + * Test for 'undoing' a single delete edit. + */ + @Test + public void testPriorState_singleDelete() + { + EditCommand command = new EditCommand(); + SequenceI seq = new Sequence("", "ABCDEF"); + SequenceI ds = new Sequence("", "ABCDEF"); + seq.setDatasetSequence(ds); + SequenceI[] seqs = new SequenceI[] + { seq }; + Edit e = command.new Edit(Action.DELETE_GAP, seqs, 2, 2, '-'); + command.addEdit(e); + + Map unwound = command.priorState(false); + assertEquals("AB--CDEF", unwound.get(ds).getSequenceAsString()); + } + + /** + * Test 'undoing' a single gap insertion edit command. + */ + @Test + public void testPriorState_singleInsert() + { + EditCommand command = new EditCommand(); + SequenceI seq = new Sequence("", "AB---CDEF"); + SequenceI ds = new Sequence("", "ABCDEF"); + seq.setDatasetSequence(ds); + SequenceI[] seqs = new SequenceI[] + { seq }; + Edit e = command.new Edit(Action.INSERT_GAP, seqs, 2, 3, '-'); + command.addEdit(e); + + Map unwound = command.priorState(false); + assertEquals("ABCDEF", unwound.get(ds).getSequenceAsString()); + } + + /** + * Test that mimics 'remove all gaps' action. This generates delete gap edits + * for contiguous gaps in each sequence separately. + */ + @Test + public void testPriorState_removeGapsMultipleSeqs() + { + EditCommand command = new EditCommand(); + String original1 = "--ABC-DEF"; + String original2 = "FG-HI--J"; + String original3 = "M-NOPQ"; + + /* + * Two edits for the first sequence + */ + SequenceI seq = new Sequence("", "ABC-DEF"); + SequenceI ds1 = new Sequence("", "ABCDEF"); + seq.setDatasetSequence(ds1); + SequenceI[] seqs = new SequenceI[] + { seq }; + Edit e = command.new Edit(Action.DELETE_GAP, seqs, 0, 2, '-'); + command.addEdit(e); + seq = new Sequence("", "ABCDEF"); + seq.setDatasetSequence(ds1); + seqs = new SequenceI[] + { seq }; + e = command.new Edit(Action.DELETE_GAP, seqs, 3, 1, '-'); + command.addEdit(e); + + /* + * Two edits for the second sequence + */ + seq = new Sequence("", "FGHI--J"); + SequenceI ds2 = new Sequence("", "FGHIJ"); + seq.setDatasetSequence(ds2); + seqs = new SequenceI[] + { seq }; + e = command.new Edit(Action.DELETE_GAP, seqs, 2, 1, '-'); + command.addEdit(e); + seq = new Sequence("", "FGHIJ"); + seq.setDatasetSequence(ds2); + seqs = new SequenceI[] + { seq }; + e = command.new Edit(Action.DELETE_GAP, seqs, 4, 2, '-'); + command.addEdit(e); + + /* + * One edit for the third sequence. + */ + seq = new Sequence("", "MNOPQ"); + SequenceI ds3 = new Sequence("", "MNOPQ"); + seq.setDatasetSequence(ds3); + seqs = new SequenceI[] + { seq }; + e = command.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'); + command.addEdit(e); + + Map unwound = command.priorState(false); + assertEquals(original1, unwound.get(ds1).getSequenceAsString()); + assertEquals(original2, unwound.get(ds2).getSequenceAsString()); + assertEquals(original3, unwound.get(ds3).getSequenceAsString()); + } + + /** + * Test that mimics 'remove all gapped columns' action. This generates a + * series Delete Gap edits that each act on all sequences that share a gapped + * column region. + */ + @Test + public void testPriorState_removeGappedCols() + { + EditCommand command = new EditCommand(); + String original1 = "--ABC--DEF"; + String original2 = "-G-HI--J"; + String original3 = "-M-NO--PQ"; + + /* + * First edit deletes the first column. + */ + SequenceI seq1 = new Sequence("", "-ABC--DEF"); + SequenceI ds1 = new Sequence("", "ABCDEF"); + seq1.setDatasetSequence(ds1); + SequenceI seq2 = new Sequence("", "G-HI--J"); + SequenceI ds2 = new Sequence("", "GHIJ"); + seq2.setDatasetSequence(ds2); + SequenceI seq3 = new Sequence("", "M-NO--PQ"); + SequenceI ds3 = new Sequence("", "MNOPQ"); + seq3.setDatasetSequence(ds3); + SequenceI[] seqs = new SequenceI[] + { seq1, seq2, seq3 }; + Edit e = command.new Edit(Action.DELETE_GAP, seqs, 0, 1, '-'); + command.addEdit(e); + + /* + * Second edit deletes what is now columns 4 and 5. + */ + seq1 = new Sequence("", "-ABCDEF"); + seq1.setDatasetSequence(ds1); + seq2 = new Sequence("", "G-HIJ"); + seq2.setDatasetSequence(ds2); + seq3 = new Sequence("", "M-NOPQ"); + seq3.setDatasetSequence(ds3); + seqs = new SequenceI[] + { seq1, seq2, seq3 }; + e = command.new Edit(Action.DELETE_GAP, seqs, 4, 2, '-'); + command.addEdit(e); + Map unwound = command.priorState(false); + assertEquals(original1, unwound.get(ds1).getSequenceAsString()); + assertEquals(original2, unwound.get(ds2).getSequenceAsString()); + assertEquals(original3, unwound.get(ds3).getSequenceAsString()); + assertEquals(ds1, unwound.get(ds1).getDatasetSequence()); + assertEquals(ds2, unwound.get(ds2).getDatasetSequence()); + assertEquals(ds3, unwound.get(ds3).getDatasetSequence()); } } diff --git a/test/jalview/datamodel/AlignedCodonFrameTest.java b/test/jalview/datamodel/AlignedCodonFrameTest.java new file mode 100644 index 0000000..0e24bf6 --- /dev/null +++ b/test/jalview/datamodel/AlignedCodonFrameTest.java @@ -0,0 +1,141 @@ +package jalview.datamodel; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import jalview.util.MapList; + +import java.util.Arrays; + +import org.junit.Test; + +public class AlignedCodonFrameTest +{ + + /** + * Test the method that locates the first aligned sequence that has a mapping. + */ + @Test + public void testFindAlignedSequence() + { + AlignmentI cdna = new Alignment(new SequenceI[] + {}); + final Sequence seq1 = new Sequence("Seq1", "C-G-TA-GC"); + seq1.createDatasetSequence(); + cdna.addSequence(seq1); + final Sequence seq2 = new Sequence("Seq2", "-TA-GG-GG"); + seq2.createDatasetSequence(); + cdna.addSequence(seq2); + + AlignmentI aa = new Alignment(new SequenceI[] + {}); + final Sequence aseq1 = new Sequence("Seq1", "-P-R"); + aseq1.createDatasetSequence(); + aa.addSequence(aseq1); + final Sequence aseq2 = new Sequence("Seq2", "-LY-"); + aseq2.createDatasetSequence(); + aa.addSequence(aseq2); + + /* + * Mapping from first DNA sequence to second AA sequence. + */ + AlignedCodonFrame acf = new AlignedCodonFrame(); + + assertNull(acf.findAlignedSequence(seq1, aa)); + + MapList map = new MapList(new int[] + { 1, 6 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(seq1.getDatasetSequence(), aseq2.getDatasetSequence(), map); + + /* + * DNA seq1 maps to AA seq2 + */ + assertEquals(aa.getSequenceAt(1), + acf.findAlignedSequence(cdna + .getSequenceAt(0).getDatasetSequence(), aa)); + + assertEquals(cdna.getSequenceAt(0), + acf.findAlignedSequence(aa + .getSequenceAt(1).getDatasetSequence(), cdna)); + } + + /** + * Test the method that locates the mapped codon for a protein position. + */ + @Test + public void testGetMappedRegion() + { + // introns lower case, exons upper case + final Sequence seq1 = new Sequence("Seq1", "c-G-TA-gC-gT-T"); + seq1.createDatasetSequence(); + final Sequence seq2 = new Sequence("Seq2", "-TA-gG-Gg-CG-a"); + seq2.createDatasetSequence(); + + final Sequence aseq1 = new Sequence("Seq1", "-P-R"); + aseq1.createDatasetSequence(); + final Sequence aseq2 = new Sequence("Seq2", "-LY-"); + aseq2.createDatasetSequence(); + + /* + * First with no mappings + */ + AlignedCodonFrame acf = new AlignedCodonFrame(); + + assertNull(acf.getMappedRegion(seq1, aseq1, 1)); + + /* + * Set up the mappings for the exons (upper-case bases) + */ + MapList map = new MapList(new int[] + { 2, 4, 6, 6, 8, 9 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(seq1.getDatasetSequence(), aseq1.getDatasetSequence(), map); + map = new MapList(new int[] + { 1, 2, 4, 5, 7, 8 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(seq2.getDatasetSequence(), aseq2.getDatasetSequence(), map); + + assertEquals("[2, 4]", + Arrays.toString(acf.getMappedRegion(seq1, aseq1, 1))); + assertEquals("[6, 6, 8, 9]", + Arrays.toString(acf.getMappedRegion(seq1, aseq1, 2))); + assertEquals("[1, 2, 4, 4]", + Arrays.toString(acf.getMappedRegion(seq2, aseq2, 1))); + assertEquals("[5, 5, 7, 8]", + Arrays.toString(acf.getMappedRegion(seq2, aseq2, 2))); + + /* + * No mapping from sequence 1 to sequence 2 + */ + assertNull(acf.getMappedRegion(seq1, aseq2, 1)); + } + + @Test + public void testGetMappedCodon() + { + final Sequence seq1 = new Sequence("Seq1", "c-G-TA-gC-gT-T"); + seq1.createDatasetSequence(); + final Sequence aseq1 = new Sequence("Seq1", "-P-R"); + aseq1.createDatasetSequence(); + + /* + * First with no mappings + */ + AlignedCodonFrame acf = new AlignedCodonFrame(); + + assertNull(acf.getMappedCodon(seq1.getDatasetSequence(), 0)); + + /* + * Set up the mappings for the exons (upper-case bases) + */ + MapList map = new MapList(new int[] + { 2, 4, 6, 6, 8, 9 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(seq1.getDatasetSequence(), aseq1.getDatasetSequence(), map); + + assertEquals("[G, T, A]", Arrays.toString(acf.getMappedCodon( + aseq1.getDatasetSequence(), 1))); + assertEquals("[C, T, T]", Arrays.toString(acf.getMappedCodon( + aseq1.getDatasetSequence(), 2))); + } +} diff --git a/test/jalview/datamodel/AlignedCodonIteratorTest.java b/test/jalview/datamodel/AlignedCodonIteratorTest.java new file mode 100644 index 0000000..671c51d --- /dev/null +++ b/test/jalview/datamodel/AlignedCodonIteratorTest.java @@ -0,0 +1,135 @@ +package jalview.datamodel; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.fail; +import jalview.util.MapList; + +import java.util.Iterator; + +import org.junit.Test; + +/** + * Unit tests for Mapping$AlignedCodonIterator + * + * @author gmcarstairs + * + */ +public class AlignedCodonIteratorTest +{ + /** + * Test normal case for iterating over aligned codons. + */ + @Test + public void testNext() + { + SequenceI from = new Sequence("Seq1", "-CgC-C-cCtAG-AtG-Gc"); + from.createDatasetSequence(); + SequenceI to = new Sequence("Seq1", "-PQ-R-"); + to.createDatasetSequence(); + MapList map = new MapList(new int[] + { 1, 1, 3, 4, 6, 6, 8, 10, 12, 13 }, new int[] + { 1, 3 }, 3, 1); + Mapping m = new Mapping(to.getDatasetSequence(), map); + + Iterator codons = m.getCodonIterator(from, '-'); + AlignedCodon codon = codons.next(); + assertEquals("[1, 3, 5]", codon.toString()); + assertEquals("P", codon.product); + codon = codons.next(); + assertEquals("[8, 10, 11]", codon.toString()); + assertEquals("Q", codon.product); + codon = codons.next(); + assertEquals("[13, 15, 17]", codon.toString()); + assertEquals("R", codon.product); + assertFalse(codons.hasNext()); + } + + /** + * Test weird case where the mapping skips over a peptide. + */ + @Test + public void testNext_unmappedPeptide() + { + SequenceI from = new Sequence("Seq1", "-CgC-C-cCtAG-AtG-Gc"); + from.createDatasetSequence(); + SequenceI to = new Sequence("Seq1", "-PQ-TR-"); + to.createDatasetSequence(); + MapList map = new MapList(new int[] + { 1, 1, 3, 4, 6, 6, 8, 10, 12, 13 }, new int[] + { 1, 2, 4, 4 }, 3, 1); + Mapping m = new Mapping(to.getDatasetSequence(), map); + + Iterator codons = m.getCodonIterator(from, '-'); + AlignedCodon codon = codons.next(); + assertEquals("[1, 3, 5]", codon.toString()); + assertEquals("P", codon.product); + codon = codons.next(); + assertEquals("[8, 10, 11]", codon.toString()); + assertEquals("Q", codon.product); + codon = codons.next(); + assertEquals("[13, 15, 17]", codon.toString()); + assertEquals("R", codon.product); + assertFalse(codons.hasNext()); + } + + /** + * Test for exception thrown for an incomplete codon. + */ + @Test + public void testNext_incompleteCodon() + { + SequenceI from = new Sequence("Seq1", "-CgC-C-cCgTt"); + from.createDatasetSequence(); + SequenceI to = new Sequence("Seq1", "-PQ-R-"); + to.createDatasetSequence(); + MapList map = new MapList(new int[] + { 1, 1, 3, 4, 6, 6, 8, 8 }, new int[] + { 1, 3 }, 3, 1); + Mapping m = new Mapping(to.getDatasetSequence(), map); + + Iterator codons = m.getCodonIterator(from, '-'); + AlignedCodon codon = codons.next(); + assertEquals("[1, 3, 5]", codon.toString()); + assertEquals("P", codon.product); + try + { + codon = codons.next(); + fail("expected exception"); + } catch (IncompleteCodonException e) + { + // expected + } + } + + /** + * Test normal case for iterating over aligned codons. + */ + @Test + public void testAnother() + { + SequenceI from = new Sequence("Seq1", "TGCCATTACCAG-"); + from.createDatasetSequence(); + SequenceI to = new Sequence("Seq1", "CHYQ"); + to.createDatasetSequence(); + MapList map = new MapList(new int[] + { 1, 12 }, new int[] + { 1, 4 }, 3, 1); + Mapping m = new Mapping(to.getDatasetSequence(), map); + + Iterator codons = m.getCodonIterator(from, '-'); + AlignedCodon codon = codons.next(); + assertEquals("[0, 1, 2]", codon.toString()); + assertEquals("C", codon.product); + codon = codons.next(); + assertEquals("[3, 4, 5]", codon.toString()); + assertEquals("H", codon.product); + codon = codons.next(); + assertEquals("[6, 7, 8]", codon.toString()); + assertEquals("Y", codon.product); + codon = codons.next(); + assertEquals("[9, 10, 11]", codon.toString()); + assertEquals("Q", codon.product); + assertFalse(codons.hasNext()); + } +} diff --git a/test/jalview/datamodel/AlignedCodonTest.java b/test/jalview/datamodel/AlignedCodonTest.java new file mode 100644 index 0000000..60368b1 --- /dev/null +++ b/test/jalview/datamodel/AlignedCodonTest.java @@ -0,0 +1,28 @@ +package jalview.datamodel; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class AlignedCodonTest +{ + + @Test + public void testEquals() + { + AlignedCodon ac = new AlignedCodon(1, 3, 4); + assertTrue(ac.equals(null)); + assertFalse(ac.equals("hello")); + assertFalse(ac.equals(new AlignedCodon(1, 3, 5))); + assertTrue(ac.equals(new AlignedCodon(1, 3, 4))); + assertTrue(ac.equals(ac)); + } + + @Test + public void testToString() { + AlignedCodon ac = new AlignedCodon(1, 3, 4); + assertEquals("[1, 3, 4]", ac.toString()); + } +} diff --git a/test/jalview/datamodel/AlignmentTest.java b/test/jalview/datamodel/AlignmentTest.java index 93170b7..df98af9 100644 --- a/test/jalview/datamodel/AlignmentTest.java +++ b/test/jalview/datamodel/AlignmentTest.java @@ -4,6 +4,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import jalview.io.AppletFormatAdapter; +import jalview.io.FormatAdapter; +import jalview.util.MapList; import java.io.IOException; import java.util.Iterator; @@ -32,10 +34,45 @@ public class AlignmentTest "D.melanogaster.3 G.UGGCGCU..UAUGACGCA\n" + "#=GR D.melanogaster.3 SS (.(((...(....(((((((\n" + "//"; + + private static final String AA_SEQS_1 = + ">Seq1Name\n" + + "K-QY--L\n" + + ">Seq2Name\n" + + "-R-FP-W-\n"; + + private static final String CDNA_SEQS_1 = + ">Seq1Name\n" + + "AC-GG--CUC-CAA-CT\n" + + ">Seq2Name\n" + + "-CG-TTA--ACG---AAGT\n"; + + private static final String CDNA_SEQS_2 = + ">Seq1Name\n" + + "GCTCGUCGTACT\n" + + ">Seq2Name\n" + + "GGGTCAGGCAGT\n"; // @formatter:on + private AlignmentI al; - private Alignment al; + /** + * Helper method to load an alignment and ensure dataset sequences are set up. + * + * @param data + * @param format + * TODO + * @return + * @throws IOException + */ + protected AlignmentI loadAlignment(final String data, String format) + throws IOException + { + Alignment a = new FormatAdapter().readFile(data, + AppletFormatAdapter.PASTE, format); + a.setDataset(null); + return a; + } /* * Read in Stockholm format test data including secondary structure @@ -44,13 +81,12 @@ public class AlignmentTest @Before public void setUp() throws IOException { - al = new jalview.io.FormatAdapter().readFile(TEST_DATA, - AppletFormatAdapter.PASTE, "STH"); - for (int i = 0; i < al.getSequencesArray().length; ++i) + al = loadAlignment(TEST_DATA, "STH"); + int i = 0; + for (AlignmentAnnotation ann : al.getAlignmentAnnotation()) { - al.addAnnotation(al.getSequenceAt(i).getAnnotation()[0]); - al.getSequenceAt(i).getAnnotation()[0].setCalcId("CalcIdFor" - + al.getSequenceAt(i).getName()); + ann.setCalcId("CalcIdFor" + al.getSequenceAt(i).getName()); + i++; } } @@ -68,4 +104,180 @@ public class AlignmentTest assertEquals("D.melanogaster.2", ann.sequenceRef.getName()); assertFalse(iter.hasNext()); } + + @Test + public void testDeleteAllAnnotations_includingAutocalculated() + { + AlignmentAnnotation aa = new AlignmentAnnotation("Consensus", + "Consensus", 0.5); + aa.autoCalculated = true; + al.addAnnotation(aa); + AlignmentAnnotation[] anns = al.getAlignmentAnnotation(); + assertEquals("Wrong number of annotations before deleting", 4, + anns.length); + al.deleteAllAnnotations(true); + assertEquals("Not all deleted", 0, al.getAlignmentAnnotation().length); + } + + @Test + public void testDeleteAllAnnotations_excludingAutocalculated() + { + AlignmentAnnotation aa = new AlignmentAnnotation("Consensus", + "Consensus", 0.5); + aa.autoCalculated = true; + al.addAnnotation(aa); + AlignmentAnnotation[] anns = al.getAlignmentAnnotation(); + assertEquals("Wrong number of annotations before deleting", 4, + anns.length); + al.deleteAllAnnotations(false); + assertEquals("Not just one annotation left", 1, + al.getAlignmentAnnotation().length); + } + + /** + * Tests for realigning as per a supplied alignment: Dna as Dna. + * + * Note: AlignedCodonFrame's state variables are named for protein-to-cDNA + * mapping, but can be exploited for a general 'sequence-to-sequence' mapping + * as here. + * + * @throws IOException + */ + @Test + public void testAlignAs_dnaAsDna() throws IOException + { + // aligned cDNA: + AlignmentI al1 = loadAlignment(CDNA_SEQS_1, "FASTA"); + // unaligned cDNA: + AlignmentI al2 = loadAlignment(CDNA_SEQS_2, "FASTA"); + + /* + * Make mappings between sequences. The 'aligned cDNA' is playing the role + * of what would normally be protein here. + */ + AlignedCodonFrame acf = new AlignedCodonFrame(); + MapList ml = new MapList(new int[] + { 1, 12 }, new int[] + { 1, 12 }, 1, 1); + acf.addMap(al2.getSequenceAt(0), al1.getSequenceAt(0), ml); + acf.addMap(al2.getSequenceAt(1), al1.getSequenceAt(1), ml); + al1.addCodonFrame(acf); + + ((Alignment) al2).alignAs(al1, false, true); + assertEquals("GC-TC--GUC-GTA-CT", al2.getSequenceAt(0) + .getSequenceAsString()); + assertEquals("-GG-GTC--AGG---CAGT", al2.getSequenceAt(1) + .getSequenceAsString()); + } + + /** + * Aligning protein from cDNA. + * + * @throws IOException + */ + @Test + public void testAlignAs_proteinAsCdna() throws IOException + { + // see also AlignmentUtilsTests + AlignmentI al1 = loadAlignment(CDNA_SEQS_1, "FASTA"); + AlignmentI al2 = loadAlignment(AA_SEQS_1, "FASTA"); + AlignedCodonFrame acf = new AlignedCodonFrame(); + MapList ml = new MapList(new int[] + { 1, 12 }, new int[] + { 1, 4 }, 3, 1); + acf.addMap(al1.getSequenceAt(0), al2.getSequenceAt(0), ml); + acf.addMap(al1.getSequenceAt(1), al2.getSequenceAt(1), ml); + al2.addCodonFrame(acf); + + ((Alignment) al2).alignAs(al1, false, true); + assertEquals("K-Q-Y-L-", al2.getSequenceAt(0).getSequenceAsString()); + assertEquals("-R-F-P-W", al2.getSequenceAt(1).getSequenceAsString()); + } + + /** + * Test aligning cdna as per protein alignment. + * + * @throws IOException + */ + @Test + public void testAlignAs_cdnaAsProtein() throws IOException + { + /* + * Load alignments and add mappings for cDNA to protein + */ + AlignmentI al1 = loadAlignment(CDNA_SEQS_1, "FASTA"); + AlignmentI al2 = loadAlignment(AA_SEQS_1, "FASTA"); + AlignedCodonFrame acf = new AlignedCodonFrame(); + MapList ml = new MapList(new int[] + { 1, 12 }, new int[] + { 1, 4 }, 3, 1); + acf.addMap(al1.getSequenceAt(0), al2.getSequenceAt(0), ml); + acf.addMap(al1.getSequenceAt(1), al2.getSequenceAt(1), ml); + al2.addCodonFrame(acf); + + /* + * Realign DNA; currently keeping existing gaps in introns only + */ + ((Alignment) al1).alignAs(al2, false, true); + assertEquals("ACG---GCUCCA------ACT", al1.getSequenceAt(0) + .getSequenceAsString()); + assertEquals("---CGT---TAACGA---AGT", al1.getSequenceAt(1) + .getSequenceAsString()); + } + + /** + * Test aligning dna as per protein alignment, for the case where there are + * introns (i.e. some dna sites have no mapping from a peptide). + * + * @throws IOException + */ + @Test + public void testAlignAs_dnaAsProtein_withIntrons() throws IOException + { + /* + * Load alignments and add mappings for cDNA to protein + */ + String dna1 = "A-Aa-gG-GCC-cT-TT"; + String dna2 = "c--CCGgg-TT--T-AA-A"; + AlignmentI al1 = loadAlignment(">Seq1\n" + dna1 + "\n>Seq2\n" + dna2 + + "\n", "FASTA"); + AlignmentI al2 = loadAlignment(">Seq1\n-P--YK\n>Seq2\nG-T--F\n", + "FASTA"); + AlignedCodonFrame acf = new AlignedCodonFrame(); + // Seq1 has intron at dna positions 3,4,9 so splice is AAG GCC TTT + // Seq2 has intron at dna positions 1,5,6 so splice is CCG TTT AAA + MapList ml1 = new MapList(new int[] + { 1, 2, 5, 8, 10, 12 }, new int[] + { 1, 3 }, 3, 1); + acf.addMap(al1.getSequenceAt(0), al2.getSequenceAt(0), ml1); + MapList ml2 = new MapList(new int[] + { 2, 4, 7, 12 }, new int[] + { 1, 3 }, 3, 1); + acf.addMap(al1.getSequenceAt(1), al2.getSequenceAt(1), ml2); + al2.addCodonFrame(acf); + + /* + * Align ignoring gaps in dna introns and exons + */ + ((Alignment) al1).alignAs(al2, false, false); + assertEquals("---AAagG------GCCcTTT", al1.getSequenceAt(0) + .getSequenceAsString()); + // note 1 gap in protein corresponds to 'gg-' in DNA (3 positions) + assertEquals("cCCGgg-TTT------AAA", al1.getSequenceAt(1) + .getSequenceAsString()); + + /* + * Reset and realign, preserving gaps in dna introns and exons + */ + al1.getSequenceAt(0).setSequence(dna1); + al1.getSequenceAt(1).setSequence(dna2); + ((Alignment) al1).alignAs(al2, true, true); + // String dna1 = "A-Aa-gG-GCC-cT-TT"; + // String dna2 = "c--CCGgg-TT--T-AA-A"; + // assumption: we include 'the greater of' protein/dna gap lengths, not both + assertEquals("---A-Aa-gG------GCC-cT-TT", al1.getSequenceAt(0) + .getSequenceAsString()); + assertEquals("c--CCGgg-TT--T------AA-A", al1.getSequenceAt(1) + .getSequenceAsString()); + } } diff --git a/test/jalview/datamodel/ColumnSelectionTest.java b/test/jalview/datamodel/ColumnSelectionTest.java new file mode 100644 index 0000000..228156a --- /dev/null +++ b/test/jalview/datamodel/ColumnSelectionTest.java @@ -0,0 +1,48 @@ +package jalview.datamodel; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; + +public class ColumnSelectionTest +{ + + @Test + public void testAddElement() + { + ColumnSelection cs = new ColumnSelection(); + cs.addElement(2); + cs.addElement(5); + List sel = cs.getSelected(); + assertEquals(2, sel.size()); + assertEquals(new Integer(2), sel.get(0)); + assertEquals(new Integer(5), sel.get(1)); + } + + /** + * Test the remove method - in particular to verify that remove(int i) removes + * the element whose value is i, _NOT_ the i'th element. + */ + @Test + public void testRemoveElement() + { + ColumnSelection cs = new ColumnSelection(); + cs.addElement(2); + cs.addElement(5); + + // removing elements not in the list has no effect + cs.removeElement(0); + cs.removeElement(1); + List sel = cs.getSelected(); + assertEquals(2, sel.size()); + assertEquals(new Integer(2), sel.get(0)); + assertEquals(new Integer(5), sel.get(1)); + + // removing an element in the list removes it + cs.removeElement(2); + assertEquals(1, sel.size()); + assertEquals(new Integer(5), sel.get(0)); + } +} diff --git a/test/jalview/datamodel/DBRefEntryTest.java b/test/jalview/datamodel/DBRefEntryTest.java new file mode 100644 index 0000000..38c7f51 --- /dev/null +++ b/test/jalview/datamodel/DBRefEntryTest.java @@ -0,0 +1,44 @@ +package jalview.datamodel; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import jalview.util.MapList; + +import org.junit.Test; + +public class DBRefEntryTest +{ + + /** + * Tests for the method that compares equality of reference (but not mapping) + */ + @Test + public void testEqualRef() + { + DBRefEntry ref1 = new DBRefEntry("UNIPROT", "1", "V71633"); + assertTrue(ref1.equalRef(ref1)); + assertFalse(ref1.equalRef(null)); + + // comparison is not case sensitive + DBRefEntry ref2 = new DBRefEntry("uniprot", "1", "v71633"); + assertTrue(ref1.equalRef(ref2)); + assertTrue(ref2.equalRef(ref1)); + + // source, version and accessionid must match + assertFalse(ref1.equalRef(new DBRefEntry("UNIPRO", "1", "V71633"))); + assertFalse(ref1.equalRef(new DBRefEntry("UNIPROT", "2", "V71633"))); + assertFalse(ref1.equalRef(new DBRefEntry("UNIPROT", "1", "V71632"))); + + // presence of or differences in mappings are ignored + ref1.setMap(new Mapping(new MapList(new int[] + { 1, 3 }, new int[] + { 1, 1 }, 3, 1))); + assertTrue(ref1.equalRef(ref2)); + assertTrue(ref2.equalRef(ref1)); + ref1.setMap(new Mapping(new MapList(new int[] + { 1, 6 }, new int[] + { 1, 2 }, 3, 1))); + assertTrue(ref1.equalRef(ref2)); + assertTrue(ref2.equalRef(ref1)); + } +} diff --git a/test/jalview/datamodel/SearchResultsTest.java b/test/jalview/datamodel/SearchResultsTest.java new file mode 100644 index 0000000..15b0314 --- /dev/null +++ b/test/jalview/datamodel/SearchResultsTest.java @@ -0,0 +1,24 @@ +package jalview.datamodel; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class SearchResultsTest +{ + + @Test + public void testToString() + { + SequenceI seq = new Sequence("", "abcdefghijklm"); + SearchResults sr = new SearchResults(); + sr.addResult(seq, 1, 1); + assertEquals("a", sr.toString()); + sr.addResult(seq, 3, 5); + assertEquals("acde", sr.toString()); + + seq = new Sequence("", "pqrstuvwxy"); + sr.addResult(seq, 6, 7); + assertEquals("acdeuv", sr.toString()); + } +} diff --git a/test/jalview/datamodel/SequenceTest.java b/test/jalview/datamodel/SequenceTest.java index 40476a0..857ee84 100644 --- a/test/jalview/datamodel/SequenceTest.java +++ b/test/jalview/datamodel/SequenceTest.java @@ -5,6 +5,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import java.util.Arrays; import java.util.List; import org.junit.Before; @@ -135,4 +136,177 @@ public class SequenceTest assertSame(annotation2, anns[1]); } + + @Test + public void testGetStartGetEnd() + { + SequenceI seq = new Sequence("test", "ABCDEF"); + assertEquals(1, seq.getStart()); + assertEquals(6, seq.getEnd()); + + seq = new Sequence("test", "--AB-C-DEF--"); + assertEquals(1, seq.getStart()); + assertEquals(6, seq.getEnd()); + + seq = new Sequence("test", "----"); + assertEquals(1, seq.getStart()); + assertEquals(0, seq.getEnd()); // ?? + } + + /** + * Tests for the method that returns an alignment column position (base 1) for + * a given sequence position (base 1). + */ + @Test + public void testFindIndex() + { + SequenceI seq = new Sequence("test", "ABCDEF"); + assertEquals(0, seq.findIndex(0)); + assertEquals(1, seq.findIndex(1)); + assertEquals(5, seq.findIndex(5)); + assertEquals(6, seq.findIndex(6)); + assertEquals(6, seq.findIndex(9)); + + seq = new Sequence("test", "-A--B-C-D-E-F--"); + assertEquals(2, seq.findIndex(1)); + assertEquals(5, seq.findIndex(2)); + assertEquals(7, seq.findIndex(3)); + + // before start returns 0 + assertEquals(0, seq.findIndex(0)); + assertEquals(0, seq.findIndex(-1)); + + // beyond end returns last residue column + assertEquals(13, seq.findIndex(99)); + + } + + /** + * Tests for the method that returns a dataset sequence position (base 1) for + * an aligned column position (base 0). + */ + @Test + public void testFindPosition() + { + SequenceI seq = new Sequence("test", "ABCDEF"); + assertEquals(1, seq.findPosition(0)); + assertEquals(6, seq.findPosition(5)); + // assertEquals(-1, seq.findPosition(6)); // fails + + seq = new Sequence("test", "AB-C-D--"); + assertEquals(1, seq.findPosition(0)); + assertEquals(2, seq.findPosition(1)); + // gap position 'finds' residue to the right (not the left as per javadoc) + assertEquals(3, seq.findPosition(2)); + assertEquals(3, seq.findPosition(3)); + assertEquals(4, seq.findPosition(4)); + assertEquals(4, seq.findPosition(5)); + // returns 1 more than sequence length if off the end ?!? + assertEquals(5, seq.findPosition(6)); + assertEquals(5, seq.findPosition(7)); + + seq = new Sequence("test", "--AB-C-DEF--"); + assertEquals(1, seq.findPosition(0)); + assertEquals(1, seq.findPosition(1)); + assertEquals(1, seq.findPosition(2)); + assertEquals(2, seq.findPosition(3)); + assertEquals(3, seq.findPosition(4)); + assertEquals(3, seq.findPosition(5)); + assertEquals(4, seq.findPosition(6)); + assertEquals(4, seq.findPosition(7)); + assertEquals(5, seq.findPosition(8)); + assertEquals(6, seq.findPosition(9)); + assertEquals(7, seq.findPosition(10)); + assertEquals(7, seq.findPosition(11)); + } + + @Test + public void testDeleteChars() + { + SequenceI seq = new Sequence("test", "ABCDEF"); + assertEquals(1, seq.getStart()); + assertEquals(6, seq.getEnd()); + seq.deleteChars(2, 3); + assertEquals("ABDEF", seq.getSequenceAsString()); + assertEquals(1, seq.getStart()); + assertEquals(5, seq.getEnd()); + + seq = new Sequence("test", "ABCDEF"); + seq.deleteChars(0, 2); + assertEquals("CDEF", seq.getSequenceAsString()); + assertEquals(3, seq.getStart()); + assertEquals(6, seq.getEnd()); + } + + @Test + public void testInsertCharAt() + { + // non-static methods: + SequenceI seq = new Sequence("test", "ABCDEF"); + seq.insertCharAt(0, 'z'); + assertEquals("zABCDEF", seq.getSequenceAsString()); + seq.insertCharAt(2, 2, 'x'); + assertEquals("zAxxBCDEF", seq.getSequenceAsString()); + // for static method see StringUtilsTest + } + + /** + * Test the method that returns an array of aligned sequence positions where + * the array index is the data sequence position (both base 0). + */ + @Test + public void testGapMap() + { + SequenceI seq = new Sequence("test", "-A--B-CD-E--F-"); + seq.createDatasetSequence(); + assertEquals("[1, 4, 6, 7, 9, 12]", Arrays.toString(seq.gapMap())); + } + + /** + * Test the method that gets sequence features, either from the sequence or + * its dataset. + */ + @Test + public void testGetSequenceFeatures() + { + SequenceI seq = new Sequence("test", "GATCAT"); + seq.createDatasetSequence(); + + assertNull(seq.getSequenceFeatures()); + + /* + * SequenceFeature on sequence + */ + SequenceFeature sf = new SequenceFeature(); + seq.addSequenceFeature(sf); + SequenceFeature[] sfs = seq.getSequenceFeatures(); + assertEquals(1, sfs.length); + assertSame(sf, sfs[0]); + + /* + * SequenceFeature on sequence and dataset sequence; returns that on + * sequence + */ + SequenceFeature sf2 = new SequenceFeature(); + seq.getDatasetSequence().addSequenceFeature(sf2); + sfs = seq.getSequenceFeatures(); + assertEquals(1, sfs.length); + assertSame(sf, sfs[0]); + + /* + * SequenceFeature on dataset sequence only + */ + seq.setSequenceFeatures(null); + sfs = seq.getSequenceFeatures(); + assertEquals(1, sfs.length); + assertSame(sf2, sfs[0]); + + /* + * Corrupt case - no SequenceFeature, dataset's dataset is the original + * sequence. Test shows no infinite loop results. + */ + seq.getDatasetSequence().setSequenceFeatures(null); + seq.getDatasetSequence().setDatasetSequence(seq); // loop! + assertNull(seq.getSequenceFeatures()); + } } diff --git a/test/jalview/ext/paradise/TestAnnotate3D.java b/test/jalview/ext/paradise/TestAnnotate3D.java index 6085e03..3365c52 100644 --- a/test/jalview/ext/paradise/TestAnnotate3D.java +++ b/test/jalview/ext/paradise/TestAnnotate3D.java @@ -21,10 +21,6 @@ package jalview.ext.paradise; import static org.junit.Assert.assertTrue; -import jalview.datamodel.AlignmentI; -import jalview.datamodel.SequenceI; -import jalview.io.FastaFile; -import jalview.io.FormatAdapter; import java.io.BufferedReader; import java.io.File; @@ -35,9 +31,13 @@ import org.junit.Assert; import org.junit.Test; import MCview.PDBfile; - import compbio.util.FileUtil; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SequenceI; +import jalview.io.FastaFile; +import jalview.io.FormatAdapter; + public class TestAnnotate3D { @@ -124,11 +124,12 @@ public class TestAnnotate3D sb.append(line + "\n"); } assertTrue("No data returned by Annotate3D", sb.length() > 0); - AlignmentI al = new FormatAdapter().readFile(sb.toString(), + final String lines = sb.toString(); + AlignmentI al = new FormatAdapter().readFile(lines, FormatAdapter.PASTE, "RNAML"); if (al == null || al.getHeight() == 0) { - System.out.println(sb.toString()); + System.out.println(lines); } assertTrue("No alignment returned.", al != null); assertTrue("No sequences in returned alignment.", al.getHeight() > 0); @@ -141,7 +142,8 @@ public class TestAnnotate3D String sq_ = new String(sq.getSequence()).toLowerCase(); for (SequenceI _struseq : pdbf.getSeqsAsArray()) { - if (new String(_struseq.getSequence()).toLowerCase().equals( + final String lowerCase = new String(_struseq.getSequence()).toLowerCase(); + if (lowerCase.equals( sq_)) { struseq = _struseq; diff --git a/test/jalview/ext/rbvi/chimera/ChimeraConnect.java b/test/jalview/ext/rbvi/chimera/ChimeraConnect.java index be4e5ea..ad4f997 100644 --- a/test/jalview/ext/rbvi/chimera/ChimeraConnect.java +++ b/test/jalview/ext/rbvi/chimera/ChimeraConnect.java @@ -1,13 +1,14 @@ package jalview.ext.rbvi.chimera; -import static org.junit.Assert.*; +import static org.junit.Assert.assertTrue; -import java.util.Arrays; import java.util.Collection; import org.junit.Test; -import ext.edu.ucsf.rbvi.strucviz2.*; +import ext.edu.ucsf.rbvi.strucviz2.ChimeraManager; +import ext.edu.ucsf.rbvi.strucviz2.ChimeraModel; +import ext.edu.ucsf.rbvi.strucviz2.StructureManager; public class ChimeraConnect { @@ -15,9 +16,10 @@ public class ChimeraConnect @Test public void test() { - StructureManager csm; + StructureManager csm; ext.edu.ucsf.rbvi.strucviz2.ChimeraManager cm = new ChimeraManager(csm = new ext.edu.ucsf.rbvi.strucviz2.StructureManager(true)); - assertTrue("Couldn't launch chimera",cm.launchChimera(csm.getChimeraPaths())); + assertTrue("Couldn't launch chimera", + cm.launchChimera(StructureManager.getChimeraPaths())); int n=0; while (n++<100) { diff --git a/test/jalview/ext/rbvi/chimera/JalviewChimeraView.java b/test/jalview/ext/rbvi/chimera/JalviewChimeraView.java index 858806b..adbf230 100644 --- a/test/jalview/ext/rbvi/chimera/JalviewChimeraView.java +++ b/test/jalview/ext/rbvi/chimera/JalviewChimeraView.java @@ -1,6 +1,11 @@ package jalview.ext.rbvi.chimera; import static org.junit.Assert.assertTrue; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceI; import jalview.gui.AlignFrame; @@ -8,10 +13,6 @@ import jalview.gui.StructureViewer; import jalview.gui.StructureViewer.ViewerType; import jalview.io.FormatAdapter; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - public class JalviewChimeraView { @@ -31,7 +32,13 @@ public class JalviewChimeraView @AfterClass public static void tearDownAfterClass() throws Exception { + try + { jalview.gui.Desktop.instance.closeAll_actionPerformed(null); + } catch (Exception e) + { + // ignore NullPointerException thrown by JMol + } } diff --git a/test/jalview/gui/AnnotationChooserTest.java b/test/jalview/gui/AnnotationChooserTest.java index 944ab9c..2b890d2 100644 --- a/test/jalview/gui/AnnotationChooserTest.java +++ b/test/jalview/gui/AnnotationChooserTest.java @@ -3,6 +3,8 @@ package jalview.gui; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; +import jalview.bin.Cache; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.Annotation; @@ -52,6 +54,12 @@ public class AnnotationChooserTest @Before public void setUp() throws IOException { + // pin down annotation sort order for test + Cache.applicationProperties.setProperty(Preferences.SORT_ANNOTATIONS, + SequenceAnnotationOrder.NONE.name()); + Cache.applicationProperties.setProperty( + Preferences.SHOW_AUTOCALC_ABOVE, Boolean.TRUE.toString()); + AlignmentI al = new jalview.io.FormatAdapter().readFile(TEST_DATA, AppletFormatAdapter.PASTE, "FASTA"); af = new AlignFrame(al, 700, 500); @@ -490,6 +498,7 @@ public class AnnotationChooserTest @Test public void testSelectType_showForSelected() { + // sequences 1 and 2 have annotations IUPred and Jmol selectSequences(1, 2); testee = new AnnotationChooser(parentPanel); final Checkbox showCheckbox = (Checkbox) getComponent(testee, 1, 0, 0); @@ -505,6 +514,7 @@ public class AnnotationChooserTest setSelected(selectedSequencesCheckbox, true); setSelected(hideCheckbox, true); setSelected(getTypeCheckbox("JMol"), true); + assertTrue(anns[5].visible); // JMol for seq3 assertFalse(anns[7].visible); // JMol for seq1 // ...now show them... @@ -738,8 +748,8 @@ public class AnnotationChooserTest assertTrue(anns[0].visible); // Conservation assertTrue(anns[1].visible); // Quality assertTrue(anns[2].visible); // Consensus - assertFalse(anns[3].visible); // IUPRED - assertTrue(anns[4].visible); // Beauty (not seq-related) + assertTrue(anns[3].visible); // Beauty (not seq-related) + assertFalse(anns[4].visible); // IUPRED assertFalse(anns[5].visible); // JMol assertFalse(anns[6].visible); // IUPRED assertFalse(anns[7].visible); // JMol diff --git a/test/jalview/gui/JvSwingUtilsTest.java b/test/jalview/gui/JvSwingUtilsTest.java new file mode 100644 index 0000000..11e6ea5 --- /dev/null +++ b/test/jalview/gui/JvSwingUtilsTest.java @@ -0,0 +1,41 @@ +package jalview.gui; + +import static org.junit.Assert.assertEquals; + +import javax.swing.JScrollBar; + +import org.junit.Test; + +public class JvSwingUtilsTest +{ + + @Test + public void testGetScrollBarProportion() + { + /* + * orientation, value, extent (width), min, max + */ + JScrollBar sb = new JScrollBar(0, 125, 50, 0, 450); + + /* + * operating range is 25 - 425 (400 wide) so value 125 is 100/400ths of this + * range + */ + assertEquals(0.25f, JvSwingUtils.getScrollBarProportion(sb), 0.001f); + } + + @Test + public void testGetScrollValueForProportion() + { + /* + * orientation, value, extent (width), min, max + */ + JScrollBar sb = new JScrollBar(0, 125, 50, 0, 450); + + /* + * operating range is 25 - 425 (400 wide) so value 125 is a quarter of this + * range + */ + assertEquals(125, JvSwingUtils.getScrollValueForProportion(sb, 0.25f)); + } +} diff --git a/test/jalview/gui/PDBSearchPanelTest.java b/test/jalview/gui/PDBSearchPanelTest.java new file mode 100644 index 0000000..17ba85a --- /dev/null +++ b/test/jalview/gui/PDBSearchPanelTest.java @@ -0,0 +1,50 @@ +package jalview.gui; + +import static org.junit.Assert.assertTrue; + +import javax.swing.JInternalFrame; +import javax.swing.JTextField; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class PDBSearchPanelTest +{ + + @Before + public void setUp() throws Exception + { + } + + @After + public void tearDown() throws Exception + { + } + + @Test + public void populateCmbSearchTargetOptionsTest() + { + PDBSearchPanel searchPanel = new PDBSearchPanel(null); + assertTrue(searchPanel.getCmbSearchTarget().getItemCount() > 0); + searchPanel.populateCmbSearchTargetOptions(); + } + + @Test + public void txt_search_ActionPerformedTest() + { + PDBSearchPanel searchPanel = new PDBSearchPanel(null); + JInternalFrame mainFrame = searchPanel.getMainFrame(); + JTextField txt_search = searchPanel.getTxtSearch(); + + assertTrue(mainFrame.getTitle().length() == 20); + assertTrue(mainFrame.getTitle() + .equalsIgnoreCase("PDB Sequence Fetcher")); + + txt_search.setText("ABC"); + + assertTrue(mainFrame.getTitle().length() > 20); + assertTrue(!mainFrame.getTitle().equalsIgnoreCase( + "PDB Sequence Fetcher")); + } +} diff --git a/test/jalview/gui/PaintRefresherTest.java b/test/jalview/gui/PaintRefresherTest.java new file mode 100644 index 0000000..1da7c8c --- /dev/null +++ b/test/jalview/gui/PaintRefresherTest.java @@ -0,0 +1,116 @@ +package jalview.gui; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import jalview.datamodel.Alignment; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; +import jalview.viewmodel.AlignmentViewport; + +import java.awt.Component; +import java.util.List; +import java.util.Map; + +import javax.swing.JPanel; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class PaintRefresherTest +{ + // TODO would prefer PaintRefresher to be a single rather than static + @Before + public void setUp() + { + PaintRefresher.components.clear(); + } + + @After + public void tearDown() + { + PaintRefresher.components.clear(); + } + + @Test + public void testRegister() + { + JPanel jp = new JPanel(); + JPanel jp2 = new JPanel(); + JPanel jp3 = new JPanel(); + JPanel jp4 = new JPanel(); + PaintRefresher.Register(jp, "22"); + PaintRefresher.Register(jp, "22"); + PaintRefresher.Register(jp2, "22"); + PaintRefresher.Register(jp3, "33"); + PaintRefresher.Register(jp3, "44"); + PaintRefresher.Register(jp4, "44"); + + Map> registered = PaintRefresher.components; + assertEquals(3, registered.size()); + assertEquals(2, registered.get("22").size()); + assertEquals(1, registered.get("33").size()); + assertEquals(2, registered.get("44").size()); + assertTrue(registered.get("22").contains(jp)); + assertTrue(registered.get("22").contains(jp2)); + assertTrue(registered.get("33").contains(jp3)); + assertTrue(registered.get("44").contains(jp3)); + assertTrue(registered.get("44").contains(jp4)); + } + + @Test + public void testRemoveComponent() + { + Map> registered = PaintRefresher.components; + + // no error with an empty PaintRefresher + JPanel jp = new JPanel(); + JPanel jp2 = new JPanel(); + PaintRefresher.RemoveComponent(jp); + assertTrue(registered.isEmpty()); + + /* + * Add then remove one item + */ + PaintRefresher.Register(jp, "11"); + PaintRefresher.RemoveComponent(jp); + assertTrue(registered.isEmpty()); + + /* + * Add one item under two ids, then remove it. It is removed from both ids, + * and the now empty id is removed. + */ + PaintRefresher.Register(jp, "11"); + PaintRefresher.Register(jp, "22"); + PaintRefresher.Register(jp2, "22"); + PaintRefresher.RemoveComponent(jp); + // "11" is removed as now empty, only 22/jp2 left + assertEquals(1, registered.size()); + assertEquals(1, registered.get("22").size()); + assertTrue(registered.get("22").contains(jp2)); + } + + @Test + public void testGetAssociatedPanels() + { + SequenceI [] seqs = new SequenceI[]{new Sequence("", "ABC")}; + Alignment al = new Alignment(seqs); + + /* + * AlignFrame constructor has side-effects: AlignmentPanel is constructed, + * and SeqCanvas, IdPanel, AlignmentPanel are all registered under the + * sequence set id of the viewport. + */ + AlignmentViewport av = new AlignViewport(al); + AlignFrame af = new AlignFrame(al, 4, 1); + AlignmentPanel ap1 = af.alignPanel; + AlignmentPanel[] panels = PaintRefresher.getAssociatedPanels(av + .getSequenceSetId()); + assertEquals(1, panels.length); + assertSame(ap1, panels[0]); + + panels = PaintRefresher.getAssociatedPanels(av.getSequenceSetId() + 1); + assertEquals(0, panels.length); + } +} diff --git a/test/jalview/gui/PopupMenuTest.java b/test/jalview/gui/PopupMenuTest.java index f7b1482..f2248a8 100644 --- a/test/jalview/gui/PopupMenuTest.java +++ b/test/jalview/gui/PopupMenuTest.java @@ -3,12 +3,6 @@ package jalview.gui; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import jalview.datamodel.AlignmentAnnotation; -import jalview.datamodel.AlignmentI; -import jalview.datamodel.SequenceI; -import jalview.io.AppletFormatAdapter; -import jalview.io.FormatAdapter; -import jalview.util.MessageManager; import java.awt.Component; import java.io.IOException; @@ -23,6 +17,12 @@ import javax.swing.JSeparator; import org.junit.Before; import org.junit.Test; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SequenceI; +import jalview.io.AppletFormatAdapter; +import jalview.io.FormatAdapter; + public class PopupMenuTest { // 4 sequences x 13 positions @@ -66,12 +66,9 @@ public class PopupMenuTest List seqs = new ArrayList(); testee.configureReferenceAnnotationsMenu(menu, seqs); assertFalse(menu.isEnabled()); - assertEquals( - MessageManager.getString("label.add_reference_annotations"), - menu.getText()); // now try null list menu.setEnabled(true); - testee.configureReferenceAnnotationsMenu(menu, seqs); + testee.configureReferenceAnnotationsMenu(menu, null); assertFalse(menu.isEnabled()); } diff --git a/test/jalview/gui/StructureChooserTest.java b/test/jalview/gui/StructureChooserTest.java new file mode 100644 index 0000000..24e8bc9 --- /dev/null +++ b/test/jalview/gui/StructureChooserTest.java @@ -0,0 +1,87 @@ +package jalview.gui; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import jalview.datamodel.DBRefEntry; +import jalview.datamodel.PDBEntry; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; + +import java.util.Vector; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class StructureChooserTest +{ + Sequence seq; + + @Before + public void setUp() throws Exception + { + seq = new Sequence("Test_Seq", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1, 26); + seq.setDatasetSequence(seq); + for (int x = 1; x < 5; x++) + { + DBRefEntry dbRef = new DBRefEntry(); + dbRef.setAccessionId("XYZ_" + x); + seq.addDBRef(dbRef); + } + + PDBEntry dbRef = new PDBEntry(); + dbRef.setId("1tim"); + + Vector pdbIds = new Vector(); + pdbIds.add(dbRef); + + seq.setPDBId(pdbIds); + } + + @After + public void tearDown() throws Exception + { + seq = null; + } + + + + @Test + public void buildQueryTest() + { + assertEquals( + "1tim OR text:XYZ_1 OR text:XYZ_2 OR text:XYZ_3 OR text:XYZ_4", + StructureChooser.buildQuery(seq)); + } + + @Test + public void populateFilterComboBoxTest() + { + SequenceI[] selectedSeqs = new SequenceI[] + { seq }; + StructureChooser sc = new StructureChooser(selectedSeqs, seq, + null); + sc.populateFilterComboBox(); + int optionsSize = sc.getCmbFilterOption().getItemCount(); + assertEquals(2, optionsSize); // if structures are not discovered then don't + // populate filter options + + sc.setStructuresDiscovered(true); + sc.populateFilterComboBox(); + optionsSize = sc.getCmbFilterOption().getItemCount(); + assertTrue(optionsSize > 2); // if structures are found, filter options + // should be populated + } + + @Test + public void fetchStructuresInfoTest() + { + SequenceI[] selectedSeqs = new SequenceI[] + { seq }; + StructureChooser sc = new StructureChooser(selectedSeqs, seq, null); + sc.fetchStructuresMetaData(); + assertTrue(sc.getDiscoveredStructuresSet() != null); + assertTrue(sc.getDiscoveredStructuresSet().size() > 0); + + } +} diff --git a/test/jalview/io/AnnotatedPDBFileInputTest.java b/test/jalview/io/AnnotatedPDBFileInputTest.java index 30b6d55..29d5549 100644 --- a/test/jalview/io/AnnotatedPDBFileInputTest.java +++ b/test/jalview/io/AnnotatedPDBFileInputTest.java @@ -7,8 +7,12 @@ import static org.junit.Assert.assertTrue; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.PDBEntry; +import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.gui.AlignFrame; +import jalview.gui.Desktop; +import jalview.structure.StructureMapping; +import jalview.structure.StructureSelectionManager; import java.io.File; import java.util.Vector; @@ -73,6 +77,48 @@ public class AnnotatedPDBFileInputTest } } + /** + * Check sequence features have been added + */ + @Test + public void checkPDBSequenceFeatures() + { + StructureSelectionManager ssm = StructureSelectionManager + .getStructureSelectionManager(Desktop.instance); + StructureMapping[] mappings = ssm.getMapping("1gaq"); + // suspect we really want to make assertions on sequence features + // in these mappings' sequencess + /* + * 1GAQ/A + */ + SequenceFeature[] sf = al.getSequenceAt(0).getSequenceFeatures(); + assertEquals(296, sf.length); + assertEquals("RESNUM", sf[0].getType()); + assertEquals("GLU:19 1gaqA", sf[0].getDescription()); + assertEquals("RESNUM", sf[295].getType()); + assertEquals("TYR:314 1gaqA", sf[295].getDescription()); + + /* + * 1GAQ/B + */ + sf = al.getSequenceAt(1).getSequenceFeatures(); + assertEquals(98, sf.length); + assertEquals("RESNUM", sf[0].getType()); + assertEquals("ALA:1 1gaqB", sf[0].getDescription()); + assertEquals("RESNUM", sf[97].getType()); + assertEquals("ALA:98 1gaqB", sf[97].getDescription()); + + /* + * 1GAQ/C + */ + sf = al.getSequenceAt(2).getSequenceFeatures(); + assertEquals(296, sf.length); + assertEquals("RESNUM", sf[0].getType()); + assertEquals("GLU:19 1gaqC", sf[0].getDescription()); + assertEquals("RESNUM", sf[295].getType()); + assertEquals("TYR:314 1gaqC", sf[295].getDescription()); + } + @Test public void checkAnnotationWiring() { diff --git a/test/jalview/io/HtmlFileTest.java b/test/jalview/io/HtmlFileTest.java index be228b8..59a5b68 100644 --- a/test/jalview/io/HtmlFileTest.java +++ b/test/jalview/io/HtmlFileTest.java @@ -1,13 +1,15 @@ package jalview.io; -import static org.junit.Assert.*; +import static org.junit.Assert.fail; +import org.junit.Ignore; import org.junit.Test; public class HtmlFileTest { @Test + @Ignore public void test() { fail("Not yet implemented"); diff --git a/test/jalview/io/Jalview2xmlTests.java b/test/jalview/io/Jalview2xmlTests.java index 0e61959..8b83934 100644 --- a/test/jalview/io/Jalview2xmlTests.java +++ b/test/jalview/io/Jalview2xmlTests.java @@ -23,6 +23,7 @@ package jalview.io; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import jalview.api.AlignmentViewPanel; +import jalview.api.ViewStyleI; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; @@ -34,6 +35,7 @@ import jalview.schemes.ColourSchemeI; import java.io.File; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; @@ -239,13 +241,13 @@ public class Jalview2xmlTests @Test public void gatherViewsHere() throws Exception { - int origCount = Desktop.getAlignframes() == null ? 0 : Desktop - .getAlignframes().length; + int origCount = Desktop.getAlignFrames() == null ? 0 : Desktop + .getAlignFrames().length; AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded( "examples/exampleFile_2_7.jar", FormatAdapter.FILE); assertTrue("Didn't read in the example file correctly.", af != null); assertTrue("Didn't gather the views in the example file.", - Desktop.getAlignframes().length == 1 + origCount); + Desktop.getAlignFrames().length == 1 + origCount); } @@ -306,4 +308,37 @@ public class Jalview2xmlTests } } + + @Test + public void testCopyViewSettings() throws Exception + { + AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded( + "examples/exampleFile_2_7.jar", FormatAdapter.FILE); + Assert.assertTrue("Didn't read in the example file correctly.", af != null); + AlignmentViewPanel sps = null, groups = null; + for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels()) + { + if ("Spinach Feredoxin Structure".equals(ap.getViewName())) + { + sps = ap; + } + if (ap.getViewName().contains("MAFFT")) + { + groups = ap; + } + } + assertTrue("Couldn't find the structure view", sps != null); + assertTrue("Couldn't find the MAFFT view", groups != null); + + ViewStyleI structureStyle = sps.getAlignViewport().getViewStyle(); + ViewStyleI groupStyle = groups.getAlignViewport().getViewStyle(); + Assert.assertFalse(structureStyle.sameStyle(groupStyle)); + + groups.getAlignViewport().setViewStyle(structureStyle); + Assert.assertFalse(groupStyle.sameStyle(groups.getAlignViewport() + .getViewStyle())); + Assert.assertTrue(structureStyle.sameStyle(groups.getAlignViewport() + .getViewStyle())); + + } } diff --git a/test/jalview/io/pdb_request_json_error.txt b/test/jalview/io/pdb_request_json_error.txt new file mode 100644 index 0000000..de14bf1 --- /dev/null +++ b/test/jalview/io/pdb_request_json_error.txt @@ -0,0 +1,17 @@ +{ + "responseHeader": { + "status": 400, + "QTime": 0, + "params": { + "sort": "", + "fl": "pdb_id", + "q": "text:abc OR text:go:abc AND molecule_sequence:['' TO *]", + "wt": "json", + "rows": "100" + } + }, + "error": { + "msg": "org.apache.solr.search.SyntaxError: Cannot parse 'text:abc OR text:go:abc AND molecule_sequence:['' TO *]': Encountered \" \":\" \": \"\" at line 1, column 19.", + "code": 400 + } +} \ No newline at end of file diff --git a/test/jalview/io/pdb_response_json.txt b/test/jalview/io/pdb_response_json.txt new file mode 100644 index 0000000..e3f3583 --- /dev/null +++ b/test/jalview/io/pdb_response_json.txt @@ -0,0 +1,176 @@ +{ + "responseHeader": { + "status": 0, + "QTime": 0, + "params": { + "sort": "", + "fl": "molecule_type,pdb_id,genus,gene_name,title", + "q": "text:abc AND molecule_sequence:['' TO *]", + "wt": "json", + "rows": "100" + } + }, + "response": { + "numFound": 931, + "start": 0, + "docs": [ + { + "pdb_id": "3qf4", + "title": "Crystal structure of a heterodimeric ABC transporter in its inward-facing conformation", + "genus": [ + "Thermotoga" + ], + "molecule_type": "Protein", + "gene_name": [ + "THEMA_03290", + "Tmari_0285", + "TM_0287" + ] + }, + { + "pdb_id": "4wbs", + "title": "Crystal structure of an ABC transporter related protein from Burkholderia phymatum", + "genus": [ + "Burkholderia" + ], + "molecule_type": "Protein", + "gene_name": [ + "Bphy_0327" + ] + }, + { + "pdb_id": "1hn0", + "title": "CRYSTAL STRUCTURE OF CHONDROITIN ABC LYASE I FROM PROTEUS VULGARIS AT 1.9 ANGSTROMS RESOLUTION", + "genus": [ + "Proteus" + ], + "molecule_type": "Protein" + }, + { + "pdb_id": "4a82", + "title": "Fitted model of staphylococcus aureus sav1866 model ABC transporter in the human cystic fibrosis transmembrane conductance regulator volume map EMD-1966.", + "genus": [ + "Homo" + ], + "molecule_type": "Protein", + "gene_name": [ + "SAV1866" + ] + }, + { + "pdb_id": "3nh6", + "title": "Nucleotide Binding Domain of human ABCB6 (apo structure)", + "genus": [ + "Homo" + ], + "molecule_type": "Protein", + "gene_name": [ + "ABCB6", + "UMAT", + "MTABC3", + "PRP" + ] + }, + { + "pdb_id": "2nq2", + "title": "An inward-facing conformation of a putative metal-chelate type ABC transporter.", + "genus": [ + "Haemophilus" + ], + "molecule_type": "Protein", + "gene_name": [ + "HI_1471" + ] + }, + { + "pdb_id": "3s4u", + "title": "Crystal structure of open, unliganded E. coli PhnD H157A", + "genus": [ + "Escherichia" + ], + "molecule_type": "Protein", + "gene_name": [ + "phnD", + "UTI89_C4699" + ] + }, + { + "pdb_id": "4q4a", + "title": "Improved model of AMP-PNP bound TM287/288", + "genus": [ + "Thermotoga" + ], + "molecule_type": "Protein", + "gene_name": [ + "TM_0288" + ] + }, + { + "pdb_id": "1oxs", + "title": "Crystal structure of GlcV, the ABC-ATPase of the glucose ABC transporter from Sulfolobus solfataricus", + "genus": [ + "Sulfolobus" + ], + "molecule_type": "Protein", + "gene_name": [ + "SSO2850" + ] + }, + { + "pdb_id": "4q4j", + "title": "Structure of crosslinked TM287/288_S498C_S520C mutant", + "genus": [ + "Thermotoga" + ], + "molecule_type": "Protein", + "gene_name": [ + "TM_0288" + ] + }, + { + "pdb_id": "1oxt", + "title": "Crystal structure of GlcV, the ABC-ATPase of the glucose ABC transporter from Sulfolobus solfataricus", + "genus": [ + "Sulfolobus" + ], + "molecule_type": "Protein", + "gene_name": [ + "SSO2850" + ] + }, + { + "pdb_id": "4q4h", + "title": "TM287/288 in its apo state", + "genus": [ + "Thermotoga" + ], + "molecule_type": "Protein", + "gene_name": [ + "TM_0288" + ] + }, + { + "pdb_id": "3qf4", + "title": "Crystal structure of a heterodimeric ABC transporter in its inward-facing conformation", + "genus": [ + "Thermotoga" + ], + "molecule_type": "Protein", + "gene_name": [ + "TM_0288" + ] + }, + { + "pdb_id": "2fgk", + "title": "Crystal structure of the ABC-cassette E631Q mutant of HlyB with bound ATP", + "genus": [ + "Escherichia" + ], + "molecule_type": "Protein", + "gene_name": [ + "hlyB" + ] + } + ] + } +} \ No newline at end of file diff --git a/test/jalview/schemes/DnaCodonTests.java b/test/jalview/schemes/DnaCodonTests.java index 6791d7c..42f17fd 100644 --- a/test/jalview/schemes/DnaCodonTests.java +++ b/test/jalview/schemes/DnaCodonTests.java @@ -20,19 +20,10 @@ */ package jalview.schemes; -import static org.junit.Assert.*; +import static org.junit.Assert.assertTrue; -import jalview.datamodel.AlignmentI; -import jalview.datamodel.ColumnSelection; -import jalview.datamodel.Sequence; -import jalview.datamodel.SequenceI; - -import java.io.IOException; import java.util.Map; -import java.util.Vector; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; public class DnaCodonTests @@ -71,13 +62,10 @@ public class DnaCodonTests // note - this test will be removed once the old codon table (including // Vectors) is removed String additional = "", failtrans = "", differentTr = ""; - for (Object aa : ResidueProperties.codonHash.keySet()) + for (String amacid : ResidueProperties.codonHash.keySet()) { - String amacid = (String) aa; - for (Object codons : ((Vector) ResidueProperties.codonHash - .get(amacid))) + for (String codon : ResidueProperties.codonHash.get(amacid)) { - String codon = (String) codons; String trans = ResidueProperties.codonTranslate(codon); String oldtrans = ResidueProperties._codonTranslate(codon); if (trans == null) diff --git a/test/jalview/schemes/ResiduePropertiesTest.java b/test/jalview/schemes/ResiduePropertiesTest.java new file mode 100644 index 0000000..b976e44 --- /dev/null +++ b/test/jalview/schemes/ResiduePropertiesTest.java @@ -0,0 +1,174 @@ +package jalview.schemes; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +public class ResiduePropertiesTest +{ + + /** + * Test 'standard' codon translations (no ambiguity codes) + */ + @Test + public void testCodonTranslate() + { + // standard translation table order column 1/2/3/4 + assertEquals("F", ResidueProperties.codonTranslate("TTT")); + assertEquals("F", ResidueProperties.codonTranslate("TTC")); + assertEquals("L", ResidueProperties.codonTranslate("TTA")); + assertEquals("L", ResidueProperties.codonTranslate("TTG")); + assertEquals("L", ResidueProperties.codonTranslate("CTT")); + assertEquals("L", ResidueProperties.codonTranslate("CTC")); + assertEquals("L", ResidueProperties.codonTranslate("CTA")); + assertEquals("L", ResidueProperties.codonTranslate("CTG")); + assertEquals("I", ResidueProperties.codonTranslate("ATT")); + assertEquals("I", ResidueProperties.codonTranslate("ATC")); + assertEquals("I", ResidueProperties.codonTranslate("ATA")); + assertEquals("M", ResidueProperties.codonTranslate("ATG")); + assertEquals("V", ResidueProperties.codonTranslate("GTT")); + assertEquals("V", ResidueProperties.codonTranslate("GTC")); + assertEquals("V", ResidueProperties.codonTranslate("GTA")); + assertEquals("V", ResidueProperties.codonTranslate("GTG")); + assertEquals("S", ResidueProperties.codonTranslate("TCT")); + assertEquals("S", ResidueProperties.codonTranslate("TCC")); + assertEquals("S", ResidueProperties.codonTranslate("TCA")); + assertEquals("S", ResidueProperties.codonTranslate("TCG")); + assertEquals("P", ResidueProperties.codonTranslate("CCT")); + assertEquals("P", ResidueProperties.codonTranslate("CCC")); + assertEquals("P", ResidueProperties.codonTranslate("CCA")); + assertEquals("P", ResidueProperties.codonTranslate("CCG")); + assertEquals("T", ResidueProperties.codonTranslate("ACT")); + assertEquals("T", ResidueProperties.codonTranslate("ACC")); + assertEquals("T", ResidueProperties.codonTranslate("ACA")); + assertEquals("T", ResidueProperties.codonTranslate("ACG")); + assertEquals("A", ResidueProperties.codonTranslate("GCT")); + assertEquals("A", ResidueProperties.codonTranslate("GCC")); + assertEquals("A", ResidueProperties.codonTranslate("GCA")); + assertEquals("A", ResidueProperties.codonTranslate("GCG")); + assertEquals("Y", ResidueProperties.codonTranslate("TAT")); + assertEquals("Y", ResidueProperties.codonTranslate("TAC")); + assertEquals("STOP", ResidueProperties.codonTranslate("TAA")); + assertEquals("STOP", ResidueProperties.codonTranslate("TAG")); + assertEquals("H", ResidueProperties.codonTranslate("CAT")); + assertEquals("H", ResidueProperties.codonTranslate("CAC")); + assertEquals("Q", ResidueProperties.codonTranslate("CAA")); + assertEquals("Q", ResidueProperties.codonTranslate("CAG")); + assertEquals("N", ResidueProperties.codonTranslate("AAT")); + assertEquals("N", ResidueProperties.codonTranslate("AAC")); + assertEquals("K", ResidueProperties.codonTranslate("AAA")); + assertEquals("K", ResidueProperties.codonTranslate("AAG")); + assertEquals("D", ResidueProperties.codonTranslate("GAT")); + assertEquals("D", ResidueProperties.codonTranslate("GAC")); + assertEquals("E", ResidueProperties.codonTranslate("GAA")); + assertEquals("E", ResidueProperties.codonTranslate("GAG")); + assertEquals("C", ResidueProperties.codonTranslate("TGT")); + assertEquals("C", ResidueProperties.codonTranslate("TGC")); + assertEquals("STOP", ResidueProperties.codonTranslate("TGA")); + assertEquals("W", ResidueProperties.codonTranslate("TGG")); + assertEquals("R", ResidueProperties.codonTranslate("CGT")); + assertEquals("R", ResidueProperties.codonTranslate("CGC")); + assertEquals("R", ResidueProperties.codonTranslate("CGA")); + assertEquals("R", ResidueProperties.codonTranslate("CGG")); + assertEquals("S", ResidueProperties.codonTranslate("AGT")); + assertEquals("S", ResidueProperties.codonTranslate("AGC")); + assertEquals("R", ResidueProperties.codonTranslate("AGA")); + assertEquals("R", ResidueProperties.codonTranslate("AGG")); + assertEquals("G", ResidueProperties.codonTranslate("GGT")); + assertEquals("G", ResidueProperties.codonTranslate("GGC")); + assertEquals("G", ResidueProperties.codonTranslate("GGA")); + assertEquals("G", ResidueProperties.codonTranslate("GGG")); + } + + /** + * Test a sample of codon translations involving ambiguity codes. Should + * return a protein value where the ambiguity does not affect the translation. + */ + @Test + public void testCodonTranslate_ambiguityCodes() + { + // Y is C or T + assertEquals("C", ResidueProperties.codonTranslate("TGY")); + // Phenylalanine first base variation + assertEquals("L", ResidueProperties.codonTranslate("YTA")); + + // W is A or T + assertEquals("L", ResidueProperties.codonTranslate("CTW")); + assertNull(ResidueProperties.codonTranslate("TTW")); + + // S is G or C + assertEquals("G", ResidueProperties.codonTranslate("GGS")); + assertNull(ResidueProperties.codonTranslate("ATS")); + + // K is T or G + assertEquals("S", ResidueProperties.codonTranslate("TCK")); + assertNull(ResidueProperties.codonTranslate("ATK")); + + // M is C or A + assertEquals("T", ResidueProperties.codonTranslate("ACM")); + // Arginine first base variation + assertEquals("R", ResidueProperties.codonTranslate("MGA")); + assertEquals("R", ResidueProperties.codonTranslate("MGG")); + assertNull(ResidueProperties.codonTranslate("TAM")); + + // D is A, G or T + assertEquals("P", ResidueProperties.codonTranslate("CCD")); + assertNull(ResidueProperties.codonTranslate("AAD")); + + // V is A, C or G + assertEquals("V", ResidueProperties.codonTranslate("GTV")); + assertNull(ResidueProperties.codonTranslate("TTV")); + + // H is A, C or T + assertEquals("A", ResidueProperties.codonTranslate("GCH")); + assertEquals("I", ResidueProperties.codonTranslate("ATH")); + assertNull(ResidueProperties.codonTranslate("AGH")); + + // B is C, G or T + assertEquals("P", ResidueProperties.codonTranslate("CCB")); + assertNull(ResidueProperties.codonTranslate("TAB")); + + // R is A or G + // additional tests for JAL-1685 (resolved) + assertEquals("L", ResidueProperties.codonTranslate("CTR")); + assertEquals("V", ResidueProperties.codonTranslate("GTR")); + assertEquals("S", ResidueProperties.codonTranslate("TCR")); + assertEquals("P", ResidueProperties.codonTranslate("CCR")); + assertEquals("T", ResidueProperties.codonTranslate("ACR")); + assertEquals("A", ResidueProperties.codonTranslate("GCR")); + assertEquals("R", ResidueProperties.codonTranslate("CGR")); + assertEquals("G", ResidueProperties.codonTranslate("GGR")); + assertEquals("R", ResidueProperties.codonTranslate("AGR")); + assertEquals("E", ResidueProperties.codonTranslate("GAR")); + assertEquals("K", ResidueProperties.codonTranslate("AAR")); + assertEquals("L", ResidueProperties.codonTranslate("TTR")); + assertEquals("Q", ResidueProperties.codonTranslate("CAR")); + assertEquals("STOP", ResidueProperties.codonTranslate("TAR")); + assertEquals("STOP", ResidueProperties.codonTranslate("TRA")); + // Arginine first and third base ambiguity + assertEquals("R", ResidueProperties.codonTranslate("MGR")); + assertNull(ResidueProperties.codonTranslate("ATR")); + + // N is any base; 8 proteins accept any base in 3rd position + assertEquals("L", ResidueProperties.codonTranslate("CTN")); + assertEquals("V", ResidueProperties.codonTranslate("GTN")); + assertEquals("S", ResidueProperties.codonTranslate("TCN")); + assertEquals("P", ResidueProperties.codonTranslate("CCN")); + assertEquals("T", ResidueProperties.codonTranslate("ACN")); + assertEquals("A", ResidueProperties.codonTranslate("GCN")); + assertEquals("R", ResidueProperties.codonTranslate("CGN")); + assertEquals("G", ResidueProperties.codonTranslate("GGN")); + assertNull(ResidueProperties.codonTranslate("ATN")); + assertNull(ResidueProperties.codonTranslate("ANT")); + assertNull(ResidueProperties.codonTranslate("NAT")); + assertNull(ResidueProperties.codonTranslate("ANN")); + assertNull(ResidueProperties.codonTranslate("NNA")); + assertNull(ResidueProperties.codonTranslate("NNN")); + + // some random stuff + assertNull(ResidueProperties.codonTranslate("YWB")); + assertNull(ResidueProperties.codonTranslate("VHD")); + assertNull(ResidueProperties.codonTranslate("WSK")); + } +} diff --git a/test/jalview/structure/Mapping.java b/test/jalview/structure/Mapping.java index 716755b..cc8138c 100644 --- a/test/jalview/structure/Mapping.java +++ b/test/jalview/structure/Mapping.java @@ -3,6 +3,13 @@ package jalview.structure; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +import MCview.PDBfile; + import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.Annotation; import jalview.datamodel.Sequence; @@ -11,11 +18,6 @@ import jalview.gui.AlignFrame; import jalview.io.FileLoader; import jalview.io.FormatAdapter; -import org.junit.Assert; -import org.junit.Test; - -import MCview.PDBfile; - public class Mapping { @@ -27,6 +29,7 @@ public class Mapping * msd numbering, not pdb res numbering. */ @Test + @Ignore public void pdbEntryPositionMap() throws Exception { fail("This test intentionally left to fail"); @@ -109,6 +112,7 @@ public class Mapping } @Test + @Ignore public void testPDBentryMapping() throws Exception { fail("This test intentionally left to fail"); diff --git a/test/jalview/structure/StructureSelectionManagerTest.java b/test/jalview/structure/StructureSelectionManagerTest.java new file mode 100644 index 0000000..487ef2c --- /dev/null +++ b/test/jalview/structure/StructureSelectionManagerTest.java @@ -0,0 +1,175 @@ +package jalview.structure; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import jalview.datamodel.AlignedCodonFrame; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; + +public class StructureSelectionManagerTest +{ + private StructureSelectionManager ssm; + + @Before + public void setUp() + { + ssm = new StructureSelectionManager(); + } + + @Test + public void testAddMapping() + { + AlignedCodonFrame acf1 = new AlignedCodonFrame(); + AlignedCodonFrame acf2 = new AlignedCodonFrame(); + + /* + * One mapping only. + */ + ssm.addMapping(acf1); + assertEquals(1, ssm.seqmappings.size()); + assertTrue(ssm.seqmappings.contains(acf1)); + assertEquals(1, ssm.seqMappingRefCounts.size()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf1).intValue()); + + /* + * A second mapping. + */ + ssm.addMapping(acf2); + assertEquals(2, ssm.seqmappings.size()); + assertTrue(ssm.seqmappings.contains(acf1)); + assertTrue(ssm.seqmappings.contains(acf2)); + assertEquals(2, ssm.seqMappingRefCounts.size()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf1).intValue()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf2).intValue()); + + /* + * A second reference to the first mapping. + */ + ssm.addMapping(acf1); + assertEquals(2, ssm.seqmappings.size()); + assertTrue(ssm.seqmappings.contains(acf1)); + assertTrue(ssm.seqmappings.contains(acf2)); + assertEquals(2, ssm.seqMappingRefCounts.size()); + assertEquals(2, ssm.seqMappingRefCounts.get(acf1).intValue()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf2).intValue()); + } + + @Test + public void testAddMappings() + { + AlignedCodonFrame acf1 = new AlignedCodonFrame(); + AlignedCodonFrame acf2 = new AlignedCodonFrame(); + AlignedCodonFrame acf3 = new AlignedCodonFrame(); + + Set set1 = new HashSet(); + set1.add(acf1); + set1.add(acf2); + Set set2 = new HashSet(); + set2.add(acf2); + set2.add(acf3); + + /* + * Adding both sets adds acf2 twice and acf1 and acf3 once each. + */ + ssm.addMappings(set1); + ssm.addMappings(set2); + + assertEquals(3, ssm.seqmappings.size()); + assertTrue(ssm.seqmappings.contains(acf1)); + assertTrue(ssm.seqmappings.contains(acf2)); + assertTrue(ssm.seqmappings.contains(acf3)); + assertEquals(3, ssm.seqMappingRefCounts.size()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf1).intValue()); + assertEquals(2, ssm.seqMappingRefCounts.get(acf2).intValue()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf3).intValue()); + } + + @Test + public void testRemoveMapping() + { + AlignedCodonFrame acf1 = new AlignedCodonFrame(); + AlignedCodonFrame acf2 = new AlignedCodonFrame(); + ssm.addMapping(acf1); + + /* + * Add one and remove it. + */ + ssm.removeMapping(acf1); + ssm.removeMapping(acf2); + assertEquals(0, ssm.seqmappings.size()); + assertEquals(0, ssm.seqMappingRefCounts.size()); + + /* + * Add one twice and remove it once. + */ + ssm.addMapping(acf1); + ssm.addMapping(acf2); + ssm.addMapping(acf1); + ssm.removeMapping(acf1); + assertEquals(2, ssm.seqmappings.size()); + assertTrue(ssm.seqmappings.contains(acf1)); + assertTrue(ssm.seqmappings.contains(acf2)); + assertEquals(2, ssm.seqMappingRefCounts.size()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf1).intValue()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf2).intValue()); + + /* + * Remove both once more to clear the set. + */ + ssm.removeMapping(acf1); + ssm.removeMapping(acf2); + assertEquals(0, ssm.seqmappings.size()); + assertEquals(0, ssm.seqMappingRefCounts.size()); + } + + @Test + public void testRemoveMappings() + { + AlignedCodonFrame acf1 = new AlignedCodonFrame(); + AlignedCodonFrame acf2 = new AlignedCodonFrame(); + AlignedCodonFrame acf3 = new AlignedCodonFrame(); + + /* + * Initial ref counts are 3/2/1: + */ + ssm.addMapping(acf1); + ssm.addMapping(acf1); + ssm.addMapping(acf1); + ssm.addMapping(acf2); + ssm.addMapping(acf2); + ssm.addMapping(acf3); + + Set set1 = new HashSet(); + set1.add(acf1); + set1.add(acf2); + Set set2 = new HashSet(); + set2.add(acf2); + set2.add(acf3); + + /* + * Remove one ref each to acf1, acf2, counts are now 2/1/1: + */ + ssm.removeMappings(set1); + assertEquals(3, ssm.seqmappings.size()); + assertTrue(ssm.seqmappings.contains(acf1)); + assertTrue(ssm.seqmappings.contains(acf2)); + assertTrue(ssm.seqmappings.contains(acf3)); + assertEquals(3, ssm.seqMappingRefCounts.size()); + assertEquals(2, ssm.seqMappingRefCounts.get(acf1).intValue()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf2).intValue()); + assertEquals(1, ssm.seqMappingRefCounts.get(acf3).intValue()); + + /* + * Remove one ref each to acf2, acf3 - they are removed + */ + ssm.removeMappings(set2); + assertEquals(1, ssm.seqmappings.size()); + assertTrue(ssm.seqmappings.contains(acf1)); + assertEquals(1, ssm.seqMappingRefCounts.size()); + assertEquals(2, ssm.seqMappingRefCounts.get(acf1).intValue()); + } +} diff --git a/test/jalview/util/ComparisonTest.java b/test/jalview/util/ComparisonTest.java new file mode 100644 index 0000000..bfc2610 --- /dev/null +++ b/test/jalview/util/ComparisonTest.java @@ -0,0 +1,89 @@ +package jalview.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; + +import org.junit.Test; + +public class ComparisonTest +{ + + @Test + public void testIsGap() + { + assertTrue(Comparison.isGap('-')); + assertTrue(Comparison.isGap('.')); + assertTrue(Comparison.isGap(' ')); + assertFalse(Comparison.isGap('X')); + assertFalse(Comparison.isGap('x')); + assertFalse(Comparison.isGap('*')); + assertFalse(Comparison.isGap('G')); + } + + /** + * Test for isNucleotide is that sequences in a dataset are more than 85% + * AGCTU. Test is not case-sensitive and ignores gaps. + */ + @Test + public void testIsNucleotide() { + SequenceI seq = new Sequence("eightypercent", "agctuAGCPV"); + assertFalse(Comparison.isNucleotide(new SequenceI[] + { seq })); + + seq = new Sequence("eightyfivepercent", "agctuAGCPVagctuAGCUV"); + assertFalse(Comparison.isNucleotide(new SequenceI[] + { seq })); + + seq = new Sequence("nineypercent", "agctuAGCgVagctuAGCUV"); + assertTrue(Comparison.isNucleotide(new SequenceI[] + { seq })); + + seq = new Sequence("eightyfivepercentgapped", + "--agc--tuA--GCPV-a---gct-uA-GC---UV"); + assertFalse(Comparison.isNucleotide(new SequenceI[] + { seq })); + + seq = new Sequence("nineypercentgapped", + "ag--ct-u-A---GC---g----Vag--c---tuAGCUV"); + assertTrue(Comparison.isNucleotide(new SequenceI[] + { seq })); + + seq = new Sequence("allgap", "---------"); + assertFalse(Comparison.isNucleotide(new SequenceI[] + { seq })); + + seq = new Sequence("DNA", "ACTugGCCAG"); + SequenceI seq2 = new Sequence("Protein", "FLIMVSPTYW"); + assertTrue(Comparison.isNucleotide(new SequenceI[] + { seq, seq, seq, seq, seq, seq, seq, seq, seq, seq2 })); // 90% DNA + assertFalse(Comparison.isNucleotide(new SequenceI[] + { seq, seq, seq, seq, seq, seq, seq, seq, seq2, seq2 })); // 80% DNA + + seq = new Sequence("ProteinThatLooksLikeDNA", "WYATGCCTGAgtcgt"); + // 12/14 = 85.7% + assertTrue(Comparison.isNucleotide(new SequenceI[] + { seq })); + + assertFalse(Comparison.isNucleotide(null)); + } + + /** + * Test percentage identity calculation for two sequences. + */ + @Test + public void testPID_matchGaps() + { + String seq1 = "ABCDEF"; + String seq2 = "abcdef"; + assertEquals("identical", 100f, Comparison.PID(seq1, seq2), 0.001f); + + // comparison range defaults to length of first sequence + seq2 = "abcdefghijklmnopqrstuvwxyz"; + assertEquals("identical", 100f, Comparison.PID(seq1, seq2), 0.001f); + + seq2 = "a---bcdef"; + } +} diff --git a/test/jalview/util/MapListTest.java b/test/jalview/util/MapListTest.java new file mode 100644 index 0000000..f69fe40 --- /dev/null +++ b/test/jalview/util/MapListTest.java @@ -0,0 +1,501 @@ +package jalview.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +public class MapListTest +{ + + @Test + public void testSomething() + { + MapList ml = new MapList(new int[] + { 1, 5, 10, 15, 25, 20 }, new int[] + { 51, 1 }, 1, 3); + MapList ml1 = new MapList(new int[] + { 1, 3, 17, 4 }, new int[] + { 51, 1 }, 1, 3); + MapList ml2 = new MapList(new int[] + { 1, 60 }, new int[] + { 1, 20 }, 3, 1); + // test internal consistency + int to[] = new int[51]; + testMap(ml, 1, 60); + MapList mldna = new MapList(new int[] + { 2, 2, 6, 8, 12, 16 }, new int[] + { 1, 3 }, 3, 1); + int[] frm = mldna.locateInFrom(1, 1); + testLocateFrom(mldna, 1, 1, new int[] + { 2, 2, 6, 7 }); + testMap(mldna, 1, 3); + /* + * for (int from=1; from<=51; from++) { int[] too=ml.shiftTo(from); int[] + * toofrom=ml.shiftFrom(too[0]); + * System.out.println("ShiftFrom("+from+")=="+too[0]+" % + * "+too[1]+"\t+-+\tShiftTo("+too[0]+")=="+toofrom[0]+" % "+toofrom[1]); } + */ + } + + private static void testLocateFrom(MapList mldna, int i, int j, int[] ks) + { + int[] frm = mldna.locateInFrom(i, j); + Assert.assertEquals("Failed test locate from " + i + " to " + j, + Arrays.toString(frm), Arrays.toString(ks)); + } + + /** + * test routine. not incremental. + * + * @param ml + * @param fromS + * @param fromE + */ + private void testMap(MapList ml, int fromS, int fromE) + { + // todo convert to JUnit style tests + for (int from = 1; from <= 25; from++) + { + int[] too = ml.shiftFrom(from); + System.out.print("ShiftFrom(" + from + ")=="); + if (too == null) + { + System.out.print("NaN\n"); + } + else + { + System.out.print(too[0] + " % " + too[1] + " (" + too[2] + ")"); + System.out.print("\t+--+\t"); + int[] toofrom = ml.shiftTo(too[0]); + if (toofrom != null) + { + if (toofrom[0] != from) + { + System.err.println("Mapping not reflexive:" + from + " " + + too[0] + "->" + toofrom[0]); + } + System.out.println("ShiftTo(" + too[0] + ")==" + toofrom[0] + + " % " + toofrom[1] + " (" + toofrom[2] + ")"); + } + else + { + System.out.println("ShiftTo(" + too[0] + ")==" + + "NaN! - not Bijective Mapping!"); + } + } + } + int mmap[][] = ml.makeFromMap(); + System.out.println("FromMap : (" + mmap[0][0] + " " + mmap[0][1] + " " + + mmap[0][2] + " " + mmap[0][3] + " "); + for (int i = 1; i <= mmap[1].length; i++) + { + if (mmap[1][i - 1] == -1) + { + System.out.print(i + "=XXX"); + + } + else + { + System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1])); + } + if (i % 20 == 0) + { + System.out.print("\n"); + } + else + { + System.out.print(","); + } + } + // test range function + System.out.print("\nTest locateInFrom\n"); + { + int f = mmap[0][2], t = mmap[0][3]; + while (f <= t) + { + System.out.println("Range " + f + " to " + t); + int rng[] = ml.locateInFrom(f, t); + if (rng != null) + { + for (int i = 0; i < rng.length; i++) + { + System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); + } + } + else + { + System.out.println("No range!"); + } + System.out.print("\nReversed\n"); + rng = ml.locateInFrom(t, f); + if (rng != null) + { + for (int i = 0; i < rng.length; i++) + { + System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); + } + } + else + { + System.out.println("No range!"); + } + System.out.print("\n"); + f++; + t--; + } + } + System.out.print("\n"); + mmap = ml.makeToMap(); + System.out.println("ToMap : (" + mmap[0][0] + " " + mmap[0][1] + " " + + mmap[0][2] + " " + mmap[0][3] + " "); + for (int i = 1; i <= mmap[1].length; i++) + { + if (mmap[1][i - 1] == -1) + { + System.out.print(i + "=XXX"); + + } + else + { + System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1])); + } + if (i % 20 == 0) + { + System.out.print("\n"); + } + else + { + System.out.print(","); + } + } + System.out.print("\n"); + // test range function + System.out.print("\nTest locateInTo\n"); + { + int f = mmap[0][2], t = mmap[0][3]; + while (f <= t) + { + System.out.println("Range " + f + " to " + t); + int rng[] = ml.locateInTo(f, t); + if (rng != null) + { + for (int i = 0; i < rng.length; i++) + { + System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); + } + } + else + { + System.out.println("No range!"); + } + System.out.print("\nReversed\n"); + rng = ml.locateInTo(t, f); + if (rng != null) + { + for (int i = 0; i < rng.length; i++) + { + System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); + } + } + else + { + System.out.println("No range!"); + } + f++; + t--; + System.out.print("\n"); + } + } + } + + /** + * Tests for method that locates ranges in the 'from' map for given range in + * the 'to' map. + */ + @Test + public void testLocateInFrom_noIntrons() + { + /* + * Simple mapping with no introns + */ + int[] codons = new int[] + { 1, 12 }; + int[] protein = new int[] + { 1, 4 }; + MapList ml = new MapList(codons, protein, 3, 1); + assertEquals("[1, 3]", Arrays.toString(ml.locateInFrom(1, 1))); + assertEquals("[4, 6]", Arrays.toString(ml.locateInFrom(2, 2))); + assertEquals("[7, 9]", Arrays.toString(ml.locateInFrom(3, 3))); + assertEquals("[10, 12]", Arrays.toString(ml.locateInFrom(4, 4))); + assertEquals("[1, 6]", Arrays.toString(ml.locateInFrom(1, 2))); + assertEquals("[1, 9]", Arrays.toString(ml.locateInFrom(1, 3))); + assertEquals("[1, 12]", Arrays.toString(ml.locateInFrom(1, 4))); + assertEquals("[4, 9]", Arrays.toString(ml.locateInFrom(2, 3))); + assertEquals("[4, 12]", Arrays.toString(ml.locateInFrom(2, 4))); + assertEquals("[7, 12]", Arrays.toString(ml.locateInFrom(3, 4))); + assertEquals("[10, 12]", Arrays.toString(ml.locateInFrom(4, 4))); + + assertNull(ml.locateInFrom(0, 0)); + assertNull(ml.locateInFrom(1, 5)); + assertNull(ml.locateInFrom(-1, 1)); + } + + /** + * Tests for method that locates ranges in the 'from' map for given range in + * the 'to' map. + */ + @Test + public void testLocateInFrom_withIntrons() + { + /* + * Exons at positions [2, 3, 5] [6, 7, 9] [10, 12, 14] [16, 17, 18] i.e. + * 2-3, 5-7, 9-10, 12-12, 14-14, 16-18 + */ + int[] codons = + { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; + int[] protein = + { 1, 4 }; + MapList ml = new MapList(codons, protein, 3, 1); + assertEquals("[2, 3, 5, 5]", Arrays.toString(ml.locateInFrom(1, 1))); + assertEquals("[6, 7, 9, 9]", Arrays.toString(ml.locateInFrom(2, 2))); + assertEquals("[10, 10, 12, 12, 14, 14]", + Arrays.toString(ml.locateInFrom(3, 3))); + assertEquals("[16, 18]", Arrays.toString(ml.locateInFrom(4, 4))); + } + + /** + * Tests for method that locates ranges in the 'to' map for given range in the + * 'from' map. + */ + @Test + public void testLocateInTo_noIntrons() + { + /* + * Simple mapping with no introns + */ + int[] codons = new int[] + { 1, 12 }; + int[] protein = new int[] + { 1, 4 }; + MapList ml = new MapList(codons, protein, 3, 1); + assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 3))); + assertEquals("[2, 2]", Arrays.toString(ml.locateInTo(4, 6))); + assertEquals("[3, 3]", Arrays.toString(ml.locateInTo(7, 9))); + assertEquals("[4, 4]", Arrays.toString(ml.locateInTo(10, 12))); + assertEquals("[1, 2]", Arrays.toString(ml.locateInTo(1, 6))); + assertEquals("[1, 3]", Arrays.toString(ml.locateInTo(1, 9))); + assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(1, 12))); + assertEquals("[2, 2]", Arrays.toString(ml.locateInTo(4, 6))); + assertEquals("[2, 4]", Arrays.toString(ml.locateInTo(4, 12))); + + /* + * A part codon is treated as if a whole one. + */ + assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 1))); + assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 2))); + assertEquals("[1, 2]", Arrays.toString(ml.locateInTo(1, 4))); + assertEquals("[1, 3]", Arrays.toString(ml.locateInTo(2, 8))); + assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(3, 11))); + assertEquals("[2, 4]", Arrays.toString(ml.locateInTo(5, 11))); + + assertNull(ml.locateInTo(0, 0)); + assertNull(ml.locateInTo(1, 13)); + assertNull(ml.locateInTo(-1, 1)); + } + + /** + * Tests for method that locates ranges in the 'to' map for given range in the + * 'from' map. + */ + @Test + public void testLocateInTo_withIntrons() + { + /* + * Exons at positions [2, 3, 5] [6, 7, 9] [10, 12, 14] [16, 17, 18] i.e. + * 2-3, 5-7, 9-10, 12-12, 14-14, 16-18 + */ + int[] codons = + { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; + /* + * Mapped proteins at positions 1, 3, 4, 6 in the sequence + */ + int[] protein = + { 1, 1, 3, 4, 6, 6 }; + MapList ml = new MapList(codons, protein, 3, 1); + + /* + * Can't map from an unmapped position + */ + assertNull(ml.locateInTo(1, 2)); + assertNull(ml.locateInTo(2, 4)); + assertNull(ml.locateInTo(4, 4)); + + /* + * Valid range or subrange of codon1 maps to protein1. + */ + assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 2))); + assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(3, 3))); + assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(3, 5))); + assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 3))); + assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 5))); + + // codon position 6 starts the next protein: + assertEquals("[1, 1, 3, 3]", Arrays.toString(ml.locateInTo(3, 6))); + + // codon positions 7 to 17 (part) cover proteins 2/3/4 at positions 3/4/6 + assertEquals("[3, 4, 6, 6]", Arrays.toString(ml.locateInTo(7, 17))); + + } + + /** + * Test equals method. + */ + @Test + public void testEquals() + { + int[] codons = new int[] + { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; + int[] protein = new int[] + { 1, 4 }; + MapList ml = new MapList(codons, protein, 3, 1); + MapList ml1 = new MapList(codons, protein, 3, 1); // same values + MapList ml2 = new MapList(codons, protein, 2, 1); // fromRatio differs + MapList ml3 = new MapList(codons, protein, 3, 2); // toRatio differs + codons[2] = 4; + MapList ml6 = new MapList(codons, protein, 3, 1); // fromShifts differ + protein[1] = 3; + MapList ml7 = new MapList(codons, protein, 3, 1); // toShifts differ + + assertTrue(ml.equals(ml)); + assertTrue(ml.equals(ml1)); + assertTrue(ml1.equals(ml)); + + assertFalse(ml.equals(null)); + assertFalse(ml.equals("hello")); + assertFalse(ml.equals(ml2)); + assertFalse(ml.equals(ml3)); + assertFalse(ml.equals(ml6)); + assertFalse(ml.equals(ml7)); + assertFalse(ml6.equals(ml7)); + + try + { + MapList ml4 = new MapList(codons, null, 3, 1); // toShifts null + assertFalse(ml.equals(ml4)); + } catch (NullPointerException e) + { + // actually thrown by constructor before equals can be called + } + try + { + MapList ml5 = new MapList(null, protein, 3, 1); // fromShifts null + assertFalse(ml.equals(ml5)); + } catch (NullPointerException e) + { + // actually thrown by constructor before equals can be called + } + } + + /** + * Test for the method that flattens a list of ranges into a single array. + */ + @Test + public void testGetRanges() + { + List ranges = new ArrayList(); + ranges.add(new int[] + { 2, 3 }); + ranges.add(new int[] + { 5, 6 }); + assertEquals("[2, 3, 5, 6]", Arrays.toString(MapList.getRanges(ranges))); + } + + /** + * Check state after construction + */ + @Test + public void testConstructor() + { + int[] codons = + { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; + int[] protein = + { 1, 1, 3, 4, 6, 6 }; + MapList ml = new MapList(codons, protein, 3, 1); + assertEquals(3, ml.getFromRatio()); + assertEquals(2, ml.getFromLowest()); + assertEquals(18, ml.getFromHighest()); + assertEquals(1, ml.getToLowest()); + assertEquals(6, ml.getToHighest()); + assertEquals("{[2, 3], [5, 7], [9, 10], [12, 12], [14, 14], [16, 18]}", + prettyPrint(ml.getFromRanges())); + assertEquals("{[1, 1], [3, 4], [6, 6]}", prettyPrint(ml.getToRanges())); + + /* + * Also copy constructor + */ + MapList ml2 = new MapList(ml); + assertEquals(3, ml2.getFromRatio()); + assertEquals(2, ml2.getFromLowest()); + assertEquals(18, ml2.getFromHighest()); + assertEquals(1, ml2.getToLowest()); + assertEquals(6, ml2.getToHighest()); + assertEquals("{[2, 3], [5, 7], [9, 10], [12, 12], [14, 14], [16, 18]}", + prettyPrint(ml2.getFromRanges())); + assertEquals("{[1, 1], [3, 4], [6, 6]}", prettyPrint(ml2.getToRanges())); + } + + /** + * Convert a List of {[i, j], [k, l], ...} to "[[i, j], [k, l], ...]" + * + * @param ranges + * @return + */ + private String prettyPrint(List ranges) + { + StringBuilder sb = new StringBuilder(ranges.size() * 5); + boolean first = true; + sb.append("{"); + for (int[] range : ranges) + { + if (!first) + { + sb.append(", "); + } + sb.append(Arrays.toString(range)); + first = false; + } + sb.append("}"); + return sb.toString(); + } + + /** + * Test the method that creates an inverse mapping + */ + @Test + public void testGetInverse() + { + int[] codons = + { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; + int[] protein = + { 1, 1, 3, 4, 6, 6 }; + + MapList ml = new MapList(codons, protein, 3, 1); + MapList ml2 = ml.getInverse(); + assertEquals(ml.getFromRatio(), ml2.getToRatio()); + assertEquals(ml.getFromRatio(), ml2.getToRatio()); + assertEquals(ml.getToHighest(), ml2.getFromHighest()); + assertEquals(ml.getFromHighest(), ml2.getToHighest()); + assertEquals(prettyPrint(ml.getFromRanges()), + prettyPrint(ml2.getToRanges())); + assertEquals(prettyPrint(ml.getToRanges()), + prettyPrint(ml2.getFromRanges())); + } +} diff --git a/test/jalview/util/MappingUtilsTest.java b/test/jalview/util/MappingUtilsTest.java new file mode 100644 index 0000000..f32e7ff --- /dev/null +++ b/test/jalview/util/MappingUtilsTest.java @@ -0,0 +1,402 @@ +package jalview.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import jalview.api.AlignViewportI; +import jalview.datamodel.AlignedCodonFrame; +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.ColumnSelection; +import jalview.datamodel.SearchResults; +import jalview.datamodel.SearchResults.Match; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceGroup; +import jalview.gui.AlignViewport; +import jalview.io.AppletFormatAdapter; +import jalview.io.FormatAdapter; + +import java.awt.Color; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; + +import org.junit.Test; + +public class MappingUtilsTest +{ + private AlignViewportI dnaView; + private AlignViewportI proteinView; + + /** + * Simple test of mapping with no intron involved. + */ + @Test + public void testBuildSearchResults() + { + final Sequence seq1 = new Sequence("Seq1", "C-G-TA-GC"); + seq1.createDatasetSequence(); + + final Sequence aseq1 = new Sequence("Seq1", "-P-R"); + aseq1.createDatasetSequence(); + + /* + * Map dna bases 1-6 to protein residues 1-2 + */ + AlignedCodonFrame acf = new AlignedCodonFrame(); + MapList map = new MapList(new int[] + { 1, 6 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(seq1.getDatasetSequence(), aseq1.getDatasetSequence(), map); + Set acfList = Collections.singleton(acf); + + /* + * Check protein residue 1 maps to codon 1-3, 2 to codon 4-6 + */ + SearchResults sr = MappingUtils.buildSearchResults(aseq1, 1, acfList); + assertEquals(1, sr.getResults().size()); + Match m = sr.getResults().get(0); + assertEquals(seq1.getDatasetSequence(), m.getSequence()); + assertEquals(1, m.getStart()); + assertEquals(3, m.getEnd()); + sr = MappingUtils.buildSearchResults(aseq1, 2, acfList); + assertEquals(1, sr.getResults().size()); + m = sr.getResults().get(0); + assertEquals(seq1.getDatasetSequence(), m.getSequence()); + assertEquals(4, m.getStart()); + assertEquals(6, m.getEnd()); + + /* + * Check inverse mappings, from codons 1-3, 4-6 to protein 1, 2 + */ + for (int i = 1; i < 7; i++) + { + sr = MappingUtils.buildSearchResults(seq1, i, acfList); + assertEquals(1, sr.getResults().size()); + m = sr.getResults().get(0); + assertEquals(aseq1.getDatasetSequence(), m.getSequence()); + int residue = i > 3 ? 2 : 1; + assertEquals(residue, m.getStart()); + assertEquals(residue, m.getEnd()); + } + } + + /** + * Simple test of mapping with introns involved. + */ + @Test + public void testBuildSearchResults_withIntro() + { + final Sequence seq1 = new Sequence("Seq1", "C-G-TAGA-GCAGCTT"); + seq1.createDatasetSequence(); + + final Sequence aseq1 = new Sequence("Seq1", "-P-R"); + aseq1.createDatasetSequence(); + + /* + * Map dna bases [2, 4, 5], [7, 9, 11] to protein residues 1 and 2 + */ + AlignedCodonFrame acf = new AlignedCodonFrame(); + MapList map = new MapList(new int[] + { 2, 2, 4, 5, 7, 7, 9, 9, 11, 11 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(seq1.getDatasetSequence(), aseq1.getDatasetSequence(), map); + Set acfList = Collections.singleton(acf); + + /* + * Check protein residue 1 maps to [2, 4, 5] + */ + SearchResults sr = MappingUtils.buildSearchResults(aseq1, 1, acfList); + assertEquals(2, sr.getResults().size()); + Match m = sr.getResults().get(0); + assertEquals(seq1.getDatasetSequence(), m.getSequence()); + assertEquals(2, m.getStart()); + assertEquals(2, m.getEnd()); + m = sr.getResults().get(1); + assertEquals(seq1.getDatasetSequence(), m.getSequence()); + assertEquals(4, m.getStart()); + assertEquals(5, m.getEnd()); + + /* + * Check protein residue 2 maps to [7, 9, 11] + */ + sr = MappingUtils.buildSearchResults(aseq1, 2, acfList); + assertEquals(3, sr.getResults().size()); + m = sr.getResults().get(0); + assertEquals(seq1.getDatasetSequence(), m.getSequence()); + assertEquals(7, m.getStart()); + assertEquals(7, m.getEnd()); + m = sr.getResults().get(1); + assertEquals(seq1.getDatasetSequence(), m.getSequence()); + assertEquals(9, m.getStart()); + assertEquals(9, m.getEnd()); + m = sr.getResults().get(2); + assertEquals(seq1.getDatasetSequence(), m.getSequence()); + assertEquals(11, m.getStart()); + assertEquals(11, m.getEnd()); + + /* + * Check inverse mappings, from codons to protein + */ + for (int i = 1; i < 14; i++) + { + sr = MappingUtils.buildSearchResults(seq1, i, acfList); + int residue = (i == 2 || i == 4 || i == 5) ? 1 : (i == 7 || i == 9 + || i == 11 ? 2 : 0); + if (residue == 0) + { + assertEquals(0, sr.getResults().size()); + continue; + } + assertEquals(1, sr.getResults().size()); + m = sr.getResults().get(0); + assertEquals(aseq1.getDatasetSequence(), m.getSequence()); + assertEquals(residue, m.getStart()); + assertEquals(residue, m.getEnd()); + } + } + + /** + * Test mapping a sequence group. + * + * @throws IOException + */ + @Test + public void testMapSequenceGroup() throws IOException + { + /* + * Set up dna and protein Seq1/2/3 with mappings (held on the protein + * viewport). + */ + AlignmentI cdna = loadAlignment(">Seq1\nACG\n>Seq2\nTGA\n>Seq3\nTAC\n", + "FASTA"); + cdna.setDataset(null); + AlignmentI protein = loadAlignment(">Seq1\nK\n>Seq2\nL\n>Seq3\nQ\n", + "FASTA"); + protein.setDataset(null); + AlignedCodonFrame acf = new AlignedCodonFrame(); + MapList map = new MapList(new int[] + { 1, 3 }, new int[] + { 1, 1 }, 3, 1); + for (int seq = 0; seq < 3; seq++) + { + acf.addMap(cdna.getSequenceAt(seq).getDatasetSequence(), protein + .getSequenceAt(seq).getDatasetSequence(), map); + } + Set acfList = Collections.singleton(acf); + + AlignViewportI dnaView = new AlignViewport(cdna); + AlignViewportI proteinView = new AlignViewport(protein); + protein.setCodonFrames(acfList); + + /* + * Select Seq1 and Seq3 in the protein + */ + SequenceGroup sg = new SequenceGroup(); + sg.setColourText(true); + sg.setIdColour(Color.GREEN); + sg.setOutlineColour(Color.LIGHT_GRAY); + sg.addSequence(protein.getSequenceAt(0), false); + sg.addSequence(protein.getSequenceAt(2), false); + + /* + * Verify the mapped sequence group in dna + */ + SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, proteinView, dnaView); + assertTrue(mappedGroup.getColourText()); + assertSame(sg.getIdColour(), mappedGroup.getIdColour()); + assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour()); + assertEquals(2, mappedGroup.getSequences().size()); + assertSame(cdna.getSequenceAt(0), mappedGroup.getSequences().get(0)); + assertSame(cdna.getSequenceAt(2), mappedGroup.getSequences().get(1)); + + /* + * Verify mapping sequence group from dna to protein + */ + sg.clear(); + sg.addSequence(cdna.getSequenceAt(1), false); + sg.addSequence(cdna.getSequenceAt(0), false); + mappedGroup = MappingUtils.mapSequenceGroup(sg, dnaView, proteinView); + assertTrue(mappedGroup.getColourText()); + assertSame(sg.getIdColour(), mappedGroup.getIdColour()); + assertSame(sg.getOutlineColour(), mappedGroup.getOutlineColour()); + assertEquals(2, mappedGroup.getSequences().size()); + assertSame(protein.getSequenceAt(1), mappedGroup.getSequences().get(0)); + assertSame(protein.getSequenceAt(0), mappedGroup.getSequences().get(1)); + } + + /** + * Helper method to load an alignment and ensure dataset sequences are set up. + * + * @param data + * @param format + * TODO + * @return + * @throws IOException + */ + protected AlignmentI loadAlignment(final String data, String format) + throws IOException + { + Alignment a = new FormatAdapter().readFile(data, + AppletFormatAdapter.PASTE, format); + a.setDataset(null); + return a; + } + + /** + * Test mapping a column selection in protein to its dna equivalent + * + * @throws IOException + */ + @Test + public void testMapColumnSelection_proteinToDna() throws IOException + { + setupMappedAlignments(); + + ColumnSelection colsel = new ColumnSelection(); + + /* + * Column 0 in protein picks up Seq2/L, Seq3/G which map to cols 0-4 and 0-3 + * in dna respectively, overall 0-4 + */ + colsel.addElement(0); + ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, + proteinView, dnaView); + assertEquals("[0, 1, 2, 3, 4]", cs.getSelected().toString()); + + /* + * Column 1 in protein picks up Seq1/K which maps to cols 0-3 in dna + */ + colsel.clear(); + colsel.addElement(1); + cs = MappingUtils.mapColumnSelection(colsel, proteinView, dnaView); + assertEquals("[0, 1, 2, 3]", cs.getSelected().toString()); + + /* + * Column 2 in protein picks up gaps only - no mapping + */ + colsel.clear(); + colsel.addElement(2); + cs = MappingUtils.mapColumnSelection(colsel, proteinView, dnaView); + assertEquals("[]", cs.getSelected().toString()); + + /* + * Column 3 in protein picks up Seq1/P, Seq2/Q, Seq3/S which map to columns + * 6-9, 6-10, 5-8 respectively, overall to 5-10 + */ + colsel.clear(); + colsel.addElement(3); + cs = MappingUtils.mapColumnSelection(colsel, proteinView, dnaView); + assertEquals("[5, 6, 7, 8, 9, 10]", cs.getSelected().toString()); + + /* + * Combine selection of columns 1 and 3 to get a discontiguous mapped + * selection + */ + colsel.clear(); + colsel.addElement(1); + colsel.addElement(3); + cs = MappingUtils.mapColumnSelection(colsel, proteinView, dnaView); + assertEquals("[0, 1, 2, 3, 5, 6, 7, 8, 9, 10]", cs.getSelected() + .toString()); + } + + /** + * @throws IOException + */ + protected void setupMappedAlignments() throws IOException + { + /* + * Set up dna and protein Seq1/2/3 with mappings (held on the protein + * viewport). Lower case for introns. + */ + AlignmentI cdna = loadAlignment(">Seq1\nAC-GctGtC-T\n" + + ">Seq2\nTc-GA-G-T-Tc\n" + ">Seq3\nTtTT-AaCGg-\n", + "FASTA"); + cdna.setDataset(null); + AlignmentI protein = loadAlignment( + ">Seq1\n-K-P\n>Seq2\nL--Q\n>Seq3\nG--S\n", + "FASTA"); + protein.setDataset(null); + AlignedCodonFrame acf = new AlignedCodonFrame(); + MapList map = new MapList(new int[] + { 1, 3, 6, 6, 8, 9 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(cdna.getSequenceAt(0).getDatasetSequence(), protein + .getSequenceAt(0).getDatasetSequence(), map); + map = new MapList(new int[] + { 1, 1, 3, 4, 5, 7 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(cdna.getSequenceAt(1).getDatasetSequence(), protein + .getSequenceAt(1).getDatasetSequence(), map); + map = new MapList(new int[] + { 1, 1, 3, 4, 5, 5, 7, 8 }, new int[] + { 1, 2 }, 3, 1); + acf.addMap(cdna.getSequenceAt(2).getDatasetSequence(), protein + .getSequenceAt(2).getDatasetSequence(), map); + Set acfList = Collections.singleton(acf); + + dnaView = new AlignViewport(cdna); + proteinView = new AlignViewport(protein); + protein.setCodonFrames(acfList); + } + + /** + * Test mapping a column selection in dna to its protein equivalent + * + * @throws IOException + */ + @Test + public void testMapColumnSelection_dnaToProtein() throws IOException + { + setupMappedAlignments(); + + ColumnSelection colsel = new ColumnSelection(); + + /* + * Column 0 in dna picks up first bases which map to residue 1, columns 0-1 + * in protein. + */ + colsel.addElement(0); + ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, dnaView, + proteinView); + assertEquals("[0, 1]", cs.getSelected().toString()); + + /* + * Columns 3-5 in dna map to the first residues in protein Seq1, Seq2, and + * the first two in Seq3. Overall to columns 0, 1, 3 (col2 is all gaps). + */ + colsel.addElement(3); + colsel.addElement(4); + colsel.addElement(5); + cs = MappingUtils.mapColumnSelection(colsel, dnaView, proteinView); + assertEquals("[0, 1, 3]", cs.getSelected().toString()); + } + + /** + * Tests for the method that converts a series of [start, end] ranges to + * single positions + */ + @Test + public void testFlattenRanges() + { + assertEquals("[1, 2, 3, 4]", + Arrays.toString(MappingUtils.flattenRanges(new int[] + { 1, 4 }))); + assertEquals("[1, 2, 3, 4]", + Arrays.toString(MappingUtils.flattenRanges(new int[] + { 1, 2, 3, 4 }))); + assertEquals("[1, 2, 3, 4]", + Arrays.toString(MappingUtils.flattenRanges(new int[] + { 1, 1, 2, 2, 3, 3, 4, 4 }))); + assertEquals("[1, 2, 3, 4, 7, 8, 9, 12]", + Arrays.toString(MappingUtils.flattenRanges(new int[] + { 1, 4, 7, 9, 12, 12 }))); + // unpaired start position is ignored: + assertEquals("[1, 2, 3, 4, 7, 8, 9, 12]", + Arrays.toString(MappingUtils.flattenRanges(new int[] + { 1, 4, 7, 9, 12, 12, 15 }))); + } +} diff --git a/test/jalview/util/QuickSortTest.java b/test/jalview/util/QuickSortTest.java new file mode 100644 index 0000000..2293163 --- /dev/null +++ b/test/jalview/util/QuickSortTest.java @@ -0,0 +1,121 @@ +package jalview.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +public class QuickSortTest +{ + private static final String c1 = "Blue"; + + private static final String c2 = "Yellow"; + + private static final String c3 = "Orange"; + + private static final String c4 = "Green"; + + private Object[] things; + + private final Object[] sortedThings = new Object[] + { c4, c2, c1, c3 }; + + @Before + public void setUp() + { + things = new Object[] + { c1, c2, c3, c4 }; + } + + @Test + public void testSort_byIntValues() + { + int[] values = new int[] + { 3, 2, 4, 1 }; + QuickSort.sort(values, things); + assertTrue(Arrays.equals(new int[] + { 1, 2, 3, 4 }, values)); + assertTrue(Arrays.equals(sortedThings, things)); + } + + @Test + public void testSort_byFloatValues() + { + float[] values = new float[] + { 3f, 2f, 4f, 1f }; + QuickSort.sort(values, things); + assertTrue(Arrays.equals(new float[] + { 1f, 2f, 3f, 4f }, values)); + assertTrue(Arrays.equals(sortedThings, things)); + } + + @Test + public void testSort_byDoubleValues() + { + double[] values = new double[] + { 3d, 2d, 4d, 1d }; + QuickSort.sort(values, things); + assertTrue(Arrays.equals(new double[] + { 1d, 2d, 3d, 4d }, values)); + assertTrue(Arrays.equals(sortedThings, things)); + } + + /** + * Sort by String is descending order, case-sensitive + */ + @Test + public void testSort_byStringValues() + { + String[] values = new String[] + { "JOHN", "henry", "lucy", "ALISON" }; + QuickSort.sort(values, things); + assertTrue(Arrays.equals(new String[] + { "lucy", "henry", "JOHN", "ALISON" }, values)); + assertTrue(Arrays.equals(new Object[] + { c3, c2, c1, c4 }, things)); + } + + /** + * Test whether sort is stable i.e. equal values retain their mutual ordering. + */ + @Test + @Ignore + public void testSort_withDuplicates() + { + int[] values = new int[] + { 3, 4, 2, 4, 1 }; + Object [] things = new Object [] {"A", "X", "Y", "B", "Z"}; + QuickSort.sort(values, things); + assertTrue(Arrays.equals(new int[] + { 1, 2, 3, 4, 4 }, values)); + // this fails - do we care? + assertTrue(Arrays.equals(new Object[] + { "Z", "Y", "A", "X", "B" }, things)); + } + + /** + * Test that exercises sort with a mostly zero-valued sortby array. May be of + * interest to check the sort algorithm is efficient. + */ + @Test + public void testSort_MostlyZeroValues() + { + char[] residues = new char[64]; + for (int i = 0; i < 64; i++) + { + residues[i] = (char) i; + } + float[] counts = new float[64]; + counts[43] = 16; + counts[59] = 7; + counts[62] = 2; + QuickSort.sort(counts, residues); + assertEquals(43, residues[63]); + assertEquals(59, residues[62]); + assertEquals(62, residues[61]); + } +} diff --git a/test/jalview/util/ShiftListTest.java b/test/jalview/util/ShiftListTest.java new file mode 100644 index 0000000..f680d6c --- /dev/null +++ b/test/jalview/util/ShiftListTest.java @@ -0,0 +1,35 @@ +package jalview.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class ShiftListTest +{ + + @Test + public void testParseMap() + { + assertNull(ShiftList.parseMap(null)); + assertNull(ShiftList.parseMap(new int[] + {})); + + /* + * Gap map showing residues in aligned positions 2,3,6,8,9,10,12 + */ + int[] gm = new int[] + { 2, 3, 6, 8, 9, 10, 12 }; + List shifts = ShiftList.parseMap(gm).getShifts(); + assertEquals(4, shifts.size()); + + // TODO are these results (which pass) correct?? + assertEquals("[0, 2]", Arrays.toString(shifts.get(0))); + assertEquals("[4, 2]", Arrays.toString(shifts.get(1))); + assertEquals("[7, 1]", Arrays.toString(shifts.get(2))); + assertEquals("[11, 1]", Arrays.toString(shifts.get(3))); + } +} diff --git a/test/jalview/util/StringUtilsTest.java b/test/jalview/util/StringUtilsTest.java new file mode 100644 index 0000000..6930e40 --- /dev/null +++ b/test/jalview/util/StringUtilsTest.java @@ -0,0 +1,109 @@ +package jalview.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.junit.Test; + +public class StringUtilsTest +{ + + @Test + public void testInsertCharAt() + { + char[] c1 = "ABC".toCharArray(); + char[] expected = new char[] + { 'A', 'B', 'C', 'w', 'w' }; + assertTrue(Arrays.equals(expected, + StringUtils.insertCharAt(c1, 3, 2, 'w'))); + expected = new char[] + { 'A', 'B', 'C', 'w', 'w' }; + assertTrue(Arrays.equals(expected, + StringUtils.insertCharAt(c1, 4, 2, 'w'))); + assertTrue(Arrays.equals(expected, + StringUtils.insertCharAt(c1, 5, 2, 'w'))); + assertTrue(Arrays.equals(expected, + StringUtils.insertCharAt(c1, 6, 2, 'w'))); + assertTrue(Arrays.equals(expected, + StringUtils.insertCharAt(c1, 7, 2, 'w'))); + } + + @Test + public void testDeleteChars() + { + char[] c1 = "ABC".toCharArray(); + + // delete second position + assertTrue(Arrays.equals(new char[] + { 'A', 'C' }, StringUtils.deleteChars(c1, 1, 2))); + + // delete positions 1 and 2 + assertTrue(Arrays.equals(new char[] + { 'C' }, StringUtils.deleteChars(c1, 0, 2))); + + // delete positions 1-3 + assertTrue(Arrays.equals(new char[] + {}, StringUtils.deleteChars(c1, 0, 3))); + + // delete position 3 + assertTrue(Arrays.equals(new char[] + { 'A', 'B' }, StringUtils.deleteChars(c1, 2, 3))); + + // out of range deletion is ignore + assertTrue(Arrays.equals(c1, StringUtils.deleteChars(c1, 3, 4))); + } + + @Test + public void testGetLastToken() + { + assertNull(StringUtils.getLastToken(null, null)); + assertNull(StringUtils.getLastToken(null, "/")); + assertEquals("a", StringUtils.getLastToken("a", null)); + + assertEquals("abc", StringUtils.getLastToken("abc", "/")); + assertEquals("c", StringUtils.getLastToken("abc", "b")); + assertEquals("file1.dat", StringUtils.getLastToken( + "file://localhost:8080/data/examples/file1.dat", "/")); + } + + @Test + public void testSeparatorListToArray() + { + String[] result = StringUtils.separatorListToArray( + "foo=',',min='foo',max='1,2,3',fa=','", ","); + assertEquals("[foo=',', min='foo', max='1,2,3', fa=',']", + Arrays.toString(result)); + /* + * Comma nested in '' is not treated as delimiter; tokens are not trimmed + */ + result = StringUtils.separatorListToArray("minsize='2', sep=','", ","); + assertEquals("[minsize='2', sep=',']", Arrays.toString(result)); + + /* + * String delimited by | containing a quoted | (should not be treated as + * delimiter) + */ + assertEquals("[abc='|'d, ef, g]", Arrays.toString(StringUtils + .separatorListToArray("abc='|'d|ef|g", "|"))); + } + + @Test + public void testArrayToSeparatorList() + { + assertEquals("*", StringUtils.arrayToSeparatorList(null, "*")); + assertEquals("*", StringUtils.arrayToSeparatorList(new String[] + {}, "*")); + assertEquals("a*bc*cde", StringUtils.arrayToSeparatorList(new String[] + { "a", "bc", "cde" }, "*")); + assertEquals("a*cde", StringUtils.arrayToSeparatorList(new String[] + { "a", null, "cde" }, "*")); + assertEquals("a**cde", StringUtils.arrayToSeparatorList(new String[] + { "a", "", "cde" }, "*")); + // delimiter within token is not (yet) escaped + assertEquals("a*b*c*cde", StringUtils.arrayToSeparatorList(new String[] + { "a", "b*c", "cde" }, "*")); + } +} diff --git a/test/jalview/viewmodel/styles/TestviewStyle.java b/test/jalview/viewmodel/styles/TestviewStyle.java new file mode 100644 index 0000000..88ea82e --- /dev/null +++ b/test/jalview/viewmodel/styles/TestviewStyle.java @@ -0,0 +1,23 @@ +package jalview.viewmodel.styles; + +import org.junit.Assert; +import org.junit.Test; + +public class TestviewStyle +{ + + @Test + public void testSetterGetter() + { + ViewStyle orig = new ViewStyle(); + orig.setCharHeight(23); + orig.setWrappedWidth(253); + orig.setWrapAlignment(true); + ViewStyle copy = new ViewStyle(orig); + orig.setWrapAlignment(false); + Assert.assertEquals(copy.getCharHeight(), orig.getCharHeight()); + Assert.assertEquals(copy.getWrappedWidth(), orig.getWrappedWidth()); + Assert.assertEquals(copy.getWrapAlignment(), !orig.getWrapAlignment()); + } + +} diff --git a/test/jalview/ws/dbsources/PDBRestClientTest.java b/test/jalview/ws/dbsources/PDBRestClientTest.java new file mode 100644 index 0000000..ba07562 --- /dev/null +++ b/test/jalview/ws/dbsources/PDBRestClientTest.java @@ -0,0 +1,181 @@ +package jalview.ws.dbsources; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import jalview.ws.dbsources.PDBRestClient.PDBDocField; +import jalview.ws.uimodel.PDBRestRequest; +import jalview.ws.uimodel.PDBRestResponse; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class PDBRestClientTest +{ + + @Before + public void setUp() throws Exception + { + } + + @After + public void tearDown() throws Exception + { + } + + @Test + public void executeRequestTest() + { + List wantedFields = new ArrayList(); + wantedFields.add(PDBDocField.MOLECULE_TYPE); + wantedFields.add(PDBDocField.PDB_ID); + wantedFields.add(PDBDocField.GENUS); + wantedFields.add(PDBDocField.GENE_NAME); + wantedFields.add(PDBDocField.TITLE); + + PDBRestRequest request = new PDBRestRequest(); + request.setAllowEmptySeq(false); + request.setResponseSize(100); + request.setFieldToSearchBy("text:"); + request.setSearchTerm("abc"); + request.setWantedFields(wantedFields); + + PDBRestResponse response = new PDBRestClient().executeRequest(request); + assertTrue(response.getNumberOfItemsFound() > 99); + assertTrue(response.getSearchSummary() != null); + assertTrue(response.getSearchSummary().size() > 99); + } + + @Test + public void getPDBDocFieldsAsCommaDelimitedStringTest() + { + List wantedFields = new ArrayList(); + wantedFields.add(PDBDocField.MOLECULE_TYPE); + wantedFields.add(PDBDocField.PDB_ID); + wantedFields.add(PDBDocField.GENUS); + wantedFields.add(PDBDocField.GENE_NAME); + wantedFields.add(PDBDocField.TITLE); + assertEquals("molecule_type,pdb_id,genus,gene_name,title", + PDBRestClient + .getPDBDocFieldsAsCommaDelimitedString(wantedFields)); + } + + @Test + public void parsePDBJsonExceptionStringTest() + { + List wantedFields = new ArrayList(); + wantedFields.add(PDBDocField.MOLECULE_TYPE); + wantedFields.add(PDBDocField.PDB_ID); + wantedFields.add(PDBDocField.GENUS); + wantedFields.add(PDBDocField.GENE_NAME); + wantedFields.add(PDBDocField.TITLE); + + PDBRestRequest request = new PDBRestRequest(); + request.setAllowEmptySeq(false); + request.setResponseSize(100); + request.setFieldToSearchBy("text:"); + request.setSearchTerm("abc"); + request.setWantedFields(wantedFields); + + String jsonErrorResponse = ""; + try + { + jsonErrorResponse = readJsonStringFromFile("test/jalview/io/pdb_request_json_error.txt"); + } catch (IOException e) + { + e.printStackTrace(); + } + + String parsedErrorResponse = PDBRestClient + .parseJsonExceptionString(jsonErrorResponse); + String expectedErrorMsg = "org.apache.solr.search.SyntaxError: Cannot parse 'text:abc OR text:go:abc AND molecule_sequence:['' TO *]': Encountered \" \":\" \": \"\" at line 1, column 19.{\"q\":\"text:abc OR text:go:abc AND molecule_sequence:['' TO *]\",\"fl\":\"pdb_id\",\"sort\":\"\",\"rows\":\"100\",\"wt\":\"json\"}"; + + assertEquals(expectedErrorMsg, parsedErrorResponse); + } + + @Test(expected = RuntimeException.class) + public void testForExpectedRuntimeException() + { + List wantedFields = new ArrayList(); + wantedFields.add(PDBDocField.PDB_ID); + + PDBRestRequest request = new PDBRestRequest(); + request.setFieldToSearchBy("text:"); + request.setSearchTerm("abc OR text:go:abc"); + request.setWantedFields(wantedFields); + new PDBRestClient().executeRequest(request); + } + + @Test + public void parsePDBJsonResponseTest() + { + List wantedFields = new ArrayList(); + wantedFields.add(PDBDocField.MOLECULE_TYPE); + wantedFields.add(PDBDocField.PDB_ID); + wantedFields.add(PDBDocField.GENUS); + wantedFields.add(PDBDocField.GENE_NAME); + wantedFields.add(PDBDocField.TITLE); + + PDBRestRequest request = new PDBRestRequest(); + request.setAllowEmptySeq(false); + request.setWantedFields(wantedFields); + + String jsonString = ""; + try + { + jsonString = readJsonStringFromFile("test/jalview/io/pdb_response_json.txt"); + } catch (IOException e) + { + e.printStackTrace(); + } + PDBRestResponse response = PDBRestClient.parsePDBJsonResponse( + jsonString, request); + assertTrue(response.getSearchSummary() != null); + assertTrue(response.getNumberOfItemsFound() == 931); + assertTrue(response.getSearchSummary().size() == 14); + } + + @Test + public void getPDBIdColumIndexTest() + { + List wantedFields = new ArrayList(); + wantedFields.add(PDBDocField.MOLECULE_TYPE); + wantedFields.add(PDBDocField.GENUS); + wantedFields.add(PDBDocField.GENE_NAME); + wantedFields.add(PDBDocField.TITLE); + wantedFields.add(PDBDocField.PDB_ID); + assertEquals(5, PDBRestClient.getPDBIdColumIndex(wantedFields, true)); + assertEquals(4, PDBRestClient.getPDBIdColumIndex(wantedFields, false)); + } + + public String readJsonStringFromFile(String filePath) throws IOException + { + String fileContent; + BufferedReader br = new BufferedReader(new FileReader(filePath)); + try + { + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + + while (line != null) + { + sb.append(line); + sb.append(System.lineSeparator()); + line = br.readLine(); + } + fileContent = sb.toString(); + } finally + { + br.close(); + } + return fileContent; + } + + +} diff --git a/test/jalview/ws/jabaws/JalviewJabawsTestUtils.java b/test/jalview/ws/jabaws/JalviewJabawsTestUtils.java index c2b483a..f7b422a 100644 --- a/test/jalview/ws/jabaws/JalviewJabawsTestUtils.java +++ b/test/jalview/ws/jabaws/JalviewJabawsTestUtils.java @@ -22,14 +22,16 @@ package jalview.ws.jabaws; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import jalview.ws.jws2.Jws2Discoverer; import java.util.Vector; import org.junit.AfterClass; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; +import jalview.ws.jws2.Jws2Discoverer; + public class JalviewJabawsTestUtils { @@ -50,6 +52,7 @@ public class JalviewJabawsTestUtils { "http://localhost:8080/jabaws" }; @Test + @Ignore public void testAnnotExport() { fail("Not yet implemented"); diff --git a/test/jalview/ws/jabaws/RNAStructExportImport.java b/test/jalview/ws/jabaws/RNAStructExportImport.java index 7046b55..36b3196 100644 --- a/test/jalview/ws/jabaws/RNAStructExportImport.java +++ b/test/jalview/ws/jabaws/RNAStructExportImport.java @@ -80,7 +80,7 @@ public class RNAStructExportImport if (rnaalifoldws == null) { - fail("rnaalifoldws is null"); + fail("no web service"); } jalview.io.FileLoader fl = new jalview.io.FileLoader(false); diff --git a/test/jalview/ws/rest/ShmmrRSBSService.java b/test/jalview/ws/rest/ShmmrRSBSService.java index 5fc215c..c4430ad 100644 --- a/test/jalview/ws/rest/ShmmrRSBSService.java +++ b/test/jalview/ws/rest/ShmmrRSBSService.java @@ -20,26 +20,16 @@ */ package jalview.ws.rest; -import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; -import java.io.BufferedReader; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.List; import java.util.Map; -import jalview.datamodel.AlignmentI; -import jalview.datamodel.AlignmentView; -import jalview.gui.AlignFrame; -import jalview.io.FileParse; -import jalview.ws.rest.InputType; -import jalview.ws.rest.params.SeqGroupIndexVector; - -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; +import jalview.gui.AlignFrame; +import jalview.util.StringUtils; + /** * @author jimp * @@ -48,20 +38,6 @@ public class ShmmrRSBSService { @Test - public void testSeparatorListToArrayForRestServiceDescriptions() - { - assertTrue( - "separatorListToArray is faulty.", - RestServiceDescription.separatorListToArray( - "foo=',',min='foo',max='1,2,3',fa=','", ",").length == 4); - assertTrue("separatorListToArray is faulty.", - RestServiceDescription.separatorListToArray( - "minsize='2', sep=','", ",").length != 2); // probably - // should come as - // 2 - } - - @Test public void testShmmrService() { diff --git a/test/jalview/ws/seqfetcher/DbRefFetcherTest.java b/test/jalview/ws/seqfetcher/DbRefFetcherTest.java index afaadbb..7540edf 100644 --- a/test/jalview/ws/seqfetcher/DbRefFetcherTest.java +++ b/test/jalview/ws/seqfetcher/DbRefFetcherTest.java @@ -23,12 +23,6 @@ package jalview.ws.seqfetcher; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import jalview.analysis.CrossRef; -import jalview.datamodel.AlignmentI; -import jalview.datamodel.DBRefEntry; -import jalview.datamodel.DBRefSource; -import jalview.util.DBRefUtils; -import jalview.ws.SequenceFetcher; import java.util.ArrayList; import java.util.List; @@ -37,6 +31,13 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; +import jalview.analysis.CrossRef; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.DBRefEntry; +import jalview.datamodel.DBRefSource; +import jalview.util.DBRefUtils; +import jalview.ws.SequenceFetcher; + /** * @author jimp * @@ -50,6 +51,7 @@ public class DbRefFetcherTest @BeforeClass public static void setUpBeforeClass() throws Exception { + jalview.bin.Cache.initLogger(); } /** @@ -102,13 +104,33 @@ public class DbRefFetcherTest { String retrievalId = "CAA23748"; // "V00488"; DbSourceProxy embl = new SequenceFetcher().getSourceProxy(DBRefSource.EMBL).get(0); - assertNotNull("Couldn't find the EMBL retrieval client",embl); + assertNotNull("Couldn't find the EMBL retrieval client", embl); + verifyProteinNucleotideXref(retrievalId, embl); + } + + @Test + public void testEmblCDSUniprotProductRecovery() throws Exception + { + String retrievalId = "AAH29712"; + DbSourceProxy embl = new SequenceFetcher().getSourceProxy( + DBRefSource.EMBLCDS).get(0); + assertNotNull("Couldn't find the EMBL retrieval client", embl); + verifyProteinNucleotideXref(retrievalId, embl); + } + + private void verifyProteinNucleotideXref(String retrievalId, + DbSourceProxy embl) throws Exception + { AlignmentI alsq = embl.getSequenceRecords(retrievalId); assertNotNull("Couldn't find the EMBL record " + retrievalId, alsq); assertEquals("Didn't retrieve right number of records", 1, alsq.getHeight()); DBRefEntry[] dr = DBRefUtils.selectRefs(alsq.getSequenceAt(0).getDBRef(), DBRefSource.PROTEINSEQ); assertNotNull(dr); assertEquals("Expected a single Uniprot cross reference", 1, dr.length); + assertEquals("Expected cross refernce map to be one amino acid", dr[0] + .getMap().getMappedWidth(), 1); + assertEquals("Expected local refernce map to be 3 nucleotides", dr[0] + .getMap().getWidth(), 3); AlignmentI sprods = CrossRef.findXrefSequences(alsq.getSequencesArray(), true, dr[0].getSource(), alsq.getDataset()); assertNotNull( "Couldn't recover cross reference sequence from dataset. Was it ever added ?",